Oracle 需要帮助执行即时更新查询吗
我有这个查询,它没有更新到数据库中。给定的“where”子句有效。当我独立运行查询时,它工作正常,但在这个过程中它不工作。没有例外或错误。你们能帮我找出问题出在哪里吗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
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;
/