我需要创建一个sql脚本,从表表中将以下列方式构建动态sql请求: 选择ID || ','||姓名|| ','||码 来自TABLE_TEST;
表名作为输入参数接收。
我的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:无效的SQL语句
请帮忙吗?
答案 0 :(得分: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
这是一个更简单的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 :(得分:-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