【问题标题】:Stored procedure execute Immediate error with WHERE clause存储过程使用 WHERE 子句执行立即错误
【发布时间】:2015-12-01 16:55:55
【问题描述】:

我正在尝试将存档表中的一行复制到原始表中。

没有我的WHERE 子句,table2 的整个表都会被复制到 table1。 我当然不想要这个。因此,根据列出的gridview的ID值,表格将只复制ID相同的行。

当我调试这些行时,我得到了为 DisplaySup.Rows(0).Cells(2).Text 列出的正确 ID。

(     
val_ID table2.V_ID%type
) 

is 
begin 

execute immediate 'insert into table1 (select * from table2 where V_ID = val_ID)'; 
end; 

但我得到了错误

ORA-00904:“VAL_ID”:无效标识符

Table2 和 Table1 具有相同的列;所以他们都有标题为V_ID的列。我不确定为什么 Val_ID 会标记错误。

VB.net 行编码:

SupArchive.Parameters.Add("val_ID", OleDbType.VarChar).Value = DisplaySup.Rows(0).Cells(2).Text

所以我尝试引用:EXECUTE IMMEDIATE with USING clause giving errors

像这样修复 WHERE:

(     
val_ID table2.V_ID%type
) 

is 
begin 

execute immediate 'insert into table1 (select * from table2 where V_ID = '||val_ID||')'; 
end; 

但我得到错误:

ORA-00904:“val_ID”:无效标识符

关于如何修复我的存储过程有什么建议吗?

更新:

尝试按照建议进行:

(
val_ID table2.V_ID%type
)
AS
BEGIN

execute immediate 'insert into table1 (col1, col2, col3...)(select col1, col2, col3... from table2 where V_ID = :val_ID)' using val_ID;

end;

但得到错误:

ORA-00904: "col72": invalid identifier

选择语句后的col72

我的表示例(两者相同)table2的目的是当table1中的一行被删除时,table2可以重新创建被删除的用户

表1

ID CompanyName FirstName LastName ....(72 cols)

表2

ID CompanyName FirstName LastName...(72 列)

【问题讨论】:

    标签: stored-procedures oracle10g where sql-insert execute-immediate


    【解决方案1】:

    您最好在插入语句中使用绑定变量。此外,您需要列出要插入的列以及要插入的列,以避免“值过多”错误。

    例如:

    declare
      val_ID table2.V_ID%type := 1;
    begin 
      execute immediate 'insert into table1 (col1, col2, ...) (select col1, col2, ... from table2 where V_ID = :val_ID)' using val_id;
    end;
    /
    

    虽然在这种情况下完全不需要使用动态 sql,所以你可以这样做:

    declare
      val_id table2.v_id%type := 1;
    begin 
      insert into table1 (col1, col2, ...)
      select col1, col2, ...
      from   table2
      where  v_id = val_id;
    end;
    /
    

    运行过程后不要忘记提交!

    【讨论】:

    • 如果你不介意我问:=1 做什么?因为我的 val_id 被我的 gridview 单元格值填充
    • 我猜你已经把它定义为一个带有参数的存储过程 - 即。 create or replace procedure ...,对吧?我将我的定义为一个声明了变量的匿名块。由于它不是参数,因此您需要为其分配一个值,否则它将为空,因此为:=1。这纯粹是为了演示目的;您只需要专注于删除立即执行并直接使用插入语句 - 当然还有更改列的名称!
    • 我在您的第二次设置中遇到了同样的问题。我在SELECT 之后的最后一个col 标记了一个错误,指出它是invalid identifier,并在第7 行说Error Text = PL/SQL: SQL Statement ignored 。我遇到了同样的问题,这就是我尝试立即执行的原因。但是,当我立即执行时,我会收到 FROM keyword not found where expected 错误
    • 那是因为在选择的列列表末尾多了一个 )。我已经更新了我的答案以将其删除。至于为什么静态 sql 版本失败...也许如果您更新了您的问题以包括为 table1 和 table2 创建表语句,我们可以尝试调试。
    • 它们不能相同,否则不会出现任何值错误!
    猜你喜欢
    • 2011-07-06
    • 1970-01-01
    • 2023-04-05
    • 1970-01-01
    • 2011-02-08
    • 1970-01-01
    • 2018-04-07
    • 1970-01-01
    • 2014-01-24
    相关资源
    最近更新 更多