我有这个查询,它没有更新到数据库中。给定的“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;
之前我没有写过提交代码。为了清楚起见。
答案 0 :(得分:2)
我认为col_id是主键。所以在更新声明中
EXECUTE IMMEDIATE 'UPDATE ' || dest || ' SET COUNTRY_CODE = :v1 WHERE col_id = :v2'
USING l_vc_CountryCode, l_vc_ColId;
您总是最多更新一行,因此条件
SQL%ROWCOUNT > 1
永远不会为真(1不是> 1)
因此,如果您的过程中没有任何其他提交语句,则永远不会提交这些更新。
顺便说一句:这个目的是什么?
if SQL%ROWCOUNT > 1 THEN
inserts := inserts + 1;
counter := counter + 1;
IF counter > 500 THEN
counter := 0;
COMMIT;
END IF;
END IF;
为什么不在工作结束时提交?
答案 1 :(得分:1)
以下代码可以正常工作(即更新行)。 我怀疑你的错误在其他地方。
例如,如果你没有初始化COUNTER,增量仍会保留为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;
答案 2 :(得分:1)
如果您使用动态SQL在数千个更新中更改“dest”表,则可能需要重新考虑您的设计。
更好地了解你的dest并在where条件中使用绑定变量。那么你可以使用mod或类似的方式提交每个x行:
if (mod(v_ctr, 1000) = 0) then
commit;
end if;
但是对于你的例子,Marcin是正确的,如果你一次只更新一行,那么
if SQL%ROWCOUNT > 1
永远不会成真;
编辑: 知道你的“dest”表的一个简单例子:
declare
cursor sel_cur is
select col1, col2, from sourceTable where col3 = 'X';
v_ctr pls_integer := 0;
begin
for rec in sel_cur
loop
v_ctr := v_ctr + 1;
-- implicit bind variables used
update destTable
set col1 = rec.col1,
col2 = rec.col2
where col3 = 'Z';
if (mod(v_ctr, 1000) = 0) then
commit;
end if;
end loop;
exception
when others then rollback;
raise;
end;
如果使用动态SQL,则使用Oracle docs中的显式绑定变量(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;
/
如需更多阅读,请参阅here。
希望这有帮助,快乐编码
答案 3 :(得分:0)
执行立即需要显式提交。我想你检查过了吗?