2017-10-12 18 views
0

テーブルテーブルから動的SQL要求を作成するSQLスクリプトを作成するには、次のようにします。 select ID || '、' ||名前|| '、' || CODE from TABLE_TEST;テーブル列から動的SQLを選択する

テーブル名は入力パラメータとして受け取ります。

私のSQLスクリプトは次のとおりです。

spool exportTable.log 
SET HEAD OFF 
SET TRIMOUT ON 
SET TRIMSPOOL ON 
SET LINESIZE 32000 
SET PAGESIZE 0 
SET TERMOUT OFF 
SET ECHO OFF 
SET COLSEP , 
procedure CreerReq(sTable in Varchar) is 

dbms_output.put_line('dans CreerReq'); 
sqlreq VARCHAR2(2000); 
sChaine VARCHAR2(4000):='select'; 
TYPE t_tab IS TABLE OF VARCHAR2(4000); 
l_tab t_tab; 
l_tab_Id t_tab; 
l_ref_cursor SYS_REFCURSOR; 
dbms_output.put_line(sChaine); 

begin 
    sqlreq := 'select column_name from all_tab_cols WHERE table_name' || sTable; 
    dbms_output.put_line(sqlreq); 
    OPEN l_ref_cursor FOR sqlreq; 
    LOOP 
    FETCH l_ref_cursor BULK COLLECT INTO l_tab_Id,l_tab limit 1000; 
    EXIT WHEN l_tab.COUNT=0; 
    FOR i IN l_tab.first .. l_tab.last LOOP 
     sChaine:=l_tab(i) ' || ',''; 
    END LOOP; 
    CLOSE l_ref_cursor; 
    dbms_output.put_line(sChaine); 
End CreerReq; 

BEGIN 


dbms_output.put_line('&1'); 
    CreerReq(&1); 
END; 
/
spool off; 

は、しかし、これは私に次のエラーが返されます。

ORA-00900: invalid SQL statement

任意のヘルプしてください?

答えて

0
CREATE or replace FUNCTION build_select (
    p_owner  IN VARCHAR2 
    , p_table_name IN VARCHAR2 
) 
    RETURN VARCHAR2 
AS 
    l_ret VARCHAR2 (32767); 
BEGIN 
    FOR eachcol IN ( SELECT column_name 
          , LEAD (column_name) 
           OVER (
            PARTITION BY table_name ORDER BY column_id 
           ) 
           next_column 
         FROM all_tab_cols 
         WHERE owner = p_owner 
         AND table_name = p_table_name 
        ORDER BY column_id) 
    LOOP 
     l_ret := l_ret || eachcol.column_name || CASE WHEN eachcol.next_column IS NULL THEN NULL ELSE ',' END; 
    END LOOP; 

    IF l_ret IS NULL 
    THEN 
     raise_application_error (-20001, 'table ' || p_owner || '.' || p_table_name || ' not found'); 
    END IF; 

    l_ret := 'select ' || l_ret || ' from ' || p_owner || '.' || p_table_name; 

    RETURN l_ret; 
END build_select; 

それでは、それをテストしてみましょう:中

begin dbms_output.put_line(build_select('SYS', 'ALL_TAB_COLS')); end; 

結果:ここで

select OWNER,TABLE_NAME,COLUMN_NAME,DATA_TYPE,DATA_TYPE_MOD,DATA_TYPE_OWNER,DATA_LENGTH,DATA_PRECISION,DATA_SCALE,NULLABLE,COLUMN_ID,DEFAULT_LENGTH,DATA_DEFAULT,NUM_DISTINCT,LOW_VALUE,HIGH_VALUE,DENSITY,NUM_NULLS,NUM_BUCKETS,LAST_ANALYZED,SAMPLE_SIZE,CHARACTER_SET_NAME,CHAR_COL_DECL_LENGTH,GLOBAL_STATS,USER_STATS,AVG_COL_LEN,CHAR_LENGTH,CHAR_USED,V80_FMT_IMAGE,DATA_UPGRADED,HIDDEN_COLUMN,VIRTUAL_COLUMN,SEGMENT_COLUMN_ID,INTERNAL_COLUMN_ID,HISTOGRAM,QUALIFIED_COL_NAME from SYS.ALL_TAB_COLS 

はAですシンプルなbuild_select関数:

CREATE OR REPLACE FUNCTION build_select (
    p_owner  IN VARCHAR2 
    , p_table_name IN VARCHAR2 
) 
    RETURN VARCHAR2 
AS 
    l_ret VARCHAR2 (32767); 
BEGIN 
    SELECT  
      LISTAGG (column_name, ',') WITHIN GROUP (ORDER BY column_id) 
     INTO l_ret 
     FROM all_tab_cols 
    WHERE table_name = p_table_name 
     AND owner = p_owner; 

    IF l_ret IS NULL 
    THEN 
     raise_application_error (-20001, 'table ' || p_owner || '.' || p_table_name || ' not found'); 
    END IF; 

    l_ret := 'select ' || l_ret || ' from ' || p_owner || '.' || p_table_name; 

    RETURN l_ret; 
END build_select; 
-1

私はしばらくの間、Oracleで作業していません。しかし、SQL Server上でこれはどのように行うことができます。このコードを見て、それが正しい方向にあなたを指している可能性があります:

/* This stored procedure builds dynamic SQL and executes 
using sp_executesql */ 
Create Procedure sp_EmployeeSelect 
    /* Input Parameters */ 
    @EmployeeName NVarchar(100), 
    @Department NVarchar(50), 
    @Designation NVarchar(50), 
    @StartDate DateTime, 
    @EndDate DateTime, 
    @Salary Decimal(10,2) 

AS 
    Set NoCount ON 
    /* Variable Declaration */ 
    Declare @SQLQuery AS NVarchar(4000) 
    Declare @ParamDefinition AS NVarchar(2000) 
    /* Build the Transact-SQL String with the input parameters */ 
    Set @SQLQuery = 'Select * From tblEmployees where (1=1) ' 
    /* check for the condition and build the WHERE clause accordingly */ 
    If @EmployeeName Is Not Null 
     Set @SQLQuery = @SQLQuery + ' And (EmployeeName = @EmployeeName)' 

    If @Department Is Not Null 
     Set @SQLQuery = @SQLQuery + ' And (Department = @Department)' 

    If @Designation Is Not Null 
     Set @SQLQuery = @SQLQuery + ' And (Designation = @Designation)' 

    If @Salary Is Not Null 
     Set @SQLQuery = @SQLQuery + ' And (Salary >= @Salary)' 

    If (@StartDate Is Not Null) AND (@EndDate Is Not Null) 
     Set @SQLQuery = @SQLQuery + ' And (JoiningDate 
     BETWEEN @StartDate AND @EndDate)' 
    /* Specify Parameter Format for all input parameters included 
    in the stmt */ 
    Set @ParamDefinition =  ' @EmployeeName NVarchar(100), 
       @Department NVarchar(50), 
       @Designation NVarchar(50), 
       @StartDate DateTime, 
       @EndDate DateTime, 
       @Salary Decimal(10,2)' 
    /* Execute the Transact-SQL String with all parameter value's 
     Using sp_executesql Command */ 
    Execute sp_Executesql  @SQLQuery, 
       @ParamDefinition, 
       @EmployeeName, 
       @Department, 
       @Designation, 
       @StartDate, 
       @EndDate, 
       @Salary 

    If @@ERROR <> 0 GoTo ErrorHandler 
    Set NoCount OFF 
    Return(0) 

ErrorHandler: 
    Return(@@ERROR) 
GO 
関連する問題