Oracle 需要帮助执行即时更新查询吗

Oracle 需要帮助执行即时更新查询吗,oracle,plsql,Oracle,Plsql,我有这个查询,它没有更新到数据库中。给定的“where”子句有效。当我独立运行查询时,它工作正常,但在这个过程中它不工作。没有例外或错误。你们能帮我找出问题出在哪里吗 EXECUTE IMMEDIATE 'UPDATE ' || dest || ' SET COUNTRY_CODE = :v1 WHERE col_id = :v2' USING l_vc_CountryCode, l_vc_ColId; if SQL%ROWCOUNT > 1 THEN

我有这个查询,它没有更新到数据库中。给定的“where”子句有效。当我独立运行查询时,它工作正常,但在这个过程中它不工作。没有例外或错误。你们能帮我找出问题出在哪里吗

EXECUTE IMMEDIATE 'UPDATE  ' || dest || ' SET COUNTRY_CODE = :v1 WHERE col_id = :v2'
          USING l_vc_CountryCode, l_vc_ColId;

if SQL%ROWCOUNT > 1 THEN
          inserts := inserts + 1;
          counter := counter + 1;
          IF counter > 500 THEN
            counter := 0;
            COMMIT;
          END IF;
        END IF;

我以前没有编写提交代码。为了清楚起见。

执行即时需要显式提交。我想你已经检查过了?

以下代码工作正常(即更新行)。 我怀疑你的错误在别处

例如,如果您不初始化计数器,增量仍将保留为null,并且它将永远不会提交

或者,l_vc_ColId可能是错误的数据类型,并且转换无效

declare
  v_emp_id number := 7839;
  v_name varchar2(4) := 'DING';
  v_tab varchar2(3) := 'EMP';
begin
  execute immediate 'update '||v_tab||
                    ' set ename = :v_name Where empno = :v_emp_id'
     using v_name, v_emp_id;
  dbms_output.put_line('C:'||sql%rowcount);
end;

我想col_id是主键。所以在update语句中

EXECUTE IMMEDIATE 'UPDATE  ' || dest || ' SET COUNTRY_CODE = :v1 WHERE col_id = :v2'
          USING l_vc_CountryCode, l_vc_ColId;
您总是最多更新一行,因此更新条件

SQL%ROWCOUNT > 1
从不为真(1不是>1)

因此,如果您的过程中没有任何其他commit语句,您将永远不会提交这些更新

顺便问一下,这是为了什么

if SQL%ROWCOUNT > 1 THEN
          inserts := inserts + 1;
          counter := counter + 1;
          IF counter > 500 THEN
            counter := 0;
            COMMIT;
          END IF;
        END IF;

为什么不在工作结束时提交?

如果您使用动态sql在数千次更新中更改“dest”表,您可能需要重新考虑您的设计

更好地了解dest并为where条件使用绑定变量。然后,您可以使用mod或类似工具每隔x行提交一次:

if (mod(v_ctr, 1000) = 0) then
  commit;
end if;
但对于您的示例,Marcin是正确的,如果您一次只更新一行,那么

if SQL%ROWCOUNT > 1
永远不会是真的

编辑: 了解“dest”表的一个简单示例:

如果使用动态SQL,则使用Oracle文档中的显式绑定变量(using子句)的简单示例如下:

CREATE OR REPLACE PROCEDURE raise_emp_salary (column_value NUMBER, 
                             emp_column VARCHAR2, amount NUMBER) IS
   v_column VARCHAR2(30);
   sql_stmt  VARCHAR2(200);
BEGIN
-- determine if a valid column name has been given as input
  SELECT COLUMN_NAME INTO v_column FROM USER_TAB_COLS 
    WHERE TABLE_NAME = 'EMPLOYEES' AND COLUMN_NAME = emp_column;
  sql_stmt := 'UPDATE employees SET salary = salary + :1 WHERE ' 
               || v_column || ' = :2';
  EXECUTE IMMEDIATE sql_stmt USING amount, column_value;
  IF SQL%ROWCOUNT > 0 THEN
    DBMS_OUTPUT.PUT_LINE('Salaries have been updated for: ' || emp_column 
                        || ' = ' || column_value);
  END IF;
  EXCEPTION
  WHEN NO_DATA_FOUND THEN
    DBMS_OUTPUT.PUT_LINE ('Invalid Column: ' || emp_column);
END raise_emp_salary;
/
有关更多阅读,请参阅


希望这有帮助,快乐编码

是的,它已经存在了。这是我的更新代码。SQL%ROWCOUNT始终为0或小于1..:我必须从这个开始。你有500多行吗?另外,我会写>0而不是1(我想我不理解你的评论)。我知道这个代码段存在于一个循环中。在循环结束时,应该对更新行的其余部分执行类似于if inserts>0 commit的操作。你也有那个提交吗?我对PLSQL一无所知。这是分配给我的一个简单的改变。所以我查找SQL%ROWCOUNT,有人建议使用此条件进行提交。我认为这是错误的。我会仔细检查并接受Marcin的回答,但你能解释一下(mod(v_ctr,1000)=0)语句在做什么吗?mod是模数的缩写。v_ctr是for循环中的一个简单计数器,每次通过循环时递增。mod(v_ctr,1000)=0简单地说,一旦你通过循环达到pass 1000,然后做一些事情(在本例中,提交你的工作)。你介意重新表述你的问题标题,使其不那么通用吗?
CREATE OR REPLACE PROCEDURE raise_emp_salary (column_value NUMBER, 
                             emp_column VARCHAR2, amount NUMBER) IS
   v_column VARCHAR2(30);
   sql_stmt  VARCHAR2(200);
BEGIN
-- determine if a valid column name has been given as input
  SELECT COLUMN_NAME INTO v_column FROM USER_TAB_COLS 
    WHERE TABLE_NAME = 'EMPLOYEES' AND COLUMN_NAME = emp_column;
  sql_stmt := 'UPDATE employees SET salary = salary + :1 WHERE ' 
               || v_column || ' = :2';
  EXECUTE IMMEDIATE sql_stmt USING amount, column_value;
  IF SQL%ROWCOUNT > 0 THEN
    DBMS_OUTPUT.PUT_LINE('Salaries have been updated for: ' || emp_column 
                        || ' = ' || column_value);
  END IF;
  EXCEPTION
  WHEN NO_DATA_FOUND THEN
    DBMS_OUTPUT.PUT_LINE ('Invalid Column: ' || emp_column);
END raise_emp_salary;
/