测试动态查询中是否有任何更新
Test if anything was updated in dynamic query
我需要动态构建和执行 UPDATE
语句。然后我需要测试是否有任何更新。我的代码如下:
DECLARE
v_table_name text;
v_column_name text;
v_debug_flag boolean;
v_upd_stmt text;
BEGIN
select nm_table_name, replace(nm_table_name, 'CDB_', 'ID_')
into strict v_table_name, v_column_name
from m_entity e
where id=12;
v_upd_stmt := format('update %s set id_lock_usr =null, dt_lock=null where %s= returning id_lock_usr',
v_table_name,
v_column_name);
execute v_upd_stmt using p_id;
END
如何知道是否有更新?
How to know if anything was updated ?
多种选择。在 plpgsql 函数中,您可以检查 special variable FOUND
以查看最后一个 SQL 命令是否影响了任何行。
IF FOUND THEN ...
但是,对于 EXECUTE
的动态查询,请改用 GET DIAGNOSTICS
。 The manual:
Note in particular that EXECUTE
changes the output of GET DIAGNOSTICS
,
but does not change FOUND
.
相关:
- Dynamic SQL (EXECUTE) as condition for IF statement
旁白:
我发现正确转义标识符(尤其是 与大写 table 名称一样存在挥之不去的问题),甚至可能 SQL 注入。修复:
DECLARE
v_table_name text;
v_column_name text;
v_id_lock_usr integer; -- guessing the data type
i integer;
BEGIN
SELECT nm_table_name, replace(nm_table_name, 'CDB_', 'ID_')
INTO strict v_table_name, v_column_name
FROM m_entity e
WHERE id = 12;
EXECUTE format('UPDATE %I SET id_lock_usr = null, dt_lock = null
WHERE %I = RETURNING id_lock_usr'
, v_table_name,
, v_column_name)
INTO v_id_lock_usr; -- to store the *single* result from RETURNING
GET DIAGNOSTICS i = ROW_COUNT;
IF i > 0 THEN
-- do something
END IF;
END
注意 %I
而不是 %s
。
在您的情况下,如果您的查询返回的 id_lock_usr
是 NOT NULL
(可靠),您可能只是直接测试结果:
IF v_id_lock_usr IS NOT NULL ...
并且您可能希望对 table 名称进行模式限定以避免歧义。但是你必须将 schema_name.table_name
作为两个单独的标识符转义 ..
相关:
- Are PostgreSQL column names case-sensitive?
- Define table and column names as arguments in a plpgsql function?
- Table name as a PostgreSQL function parameter
我需要动态构建和执行 UPDATE
语句。然后我需要测试是否有任何更新。我的代码如下:
DECLARE
v_table_name text;
v_column_name text;
v_debug_flag boolean;
v_upd_stmt text;
BEGIN
select nm_table_name, replace(nm_table_name, 'CDB_', 'ID_')
into strict v_table_name, v_column_name
from m_entity e
where id=12;
v_upd_stmt := format('update %s set id_lock_usr =null, dt_lock=null where %s= returning id_lock_usr',
v_table_name,
v_column_name);
execute v_upd_stmt using p_id;
END
如何知道是否有更新?
How to know if anything was updated ?
多种选择。在 plpgsql 函数中,您可以检查 special variable FOUND
以查看最后一个 SQL 命令是否影响了任何行。
IF FOUND THEN ...
但是,对于 EXECUTE
的动态查询,请改用 GET DIAGNOSTICS
。 The manual:
Note in particular that
EXECUTE
changes the output ofGET DIAGNOSTICS
, but does not changeFOUND
.
相关:
- Dynamic SQL (EXECUTE) as condition for IF statement
旁白: 我发现正确转义标识符(尤其是 与大写 table 名称一样存在挥之不去的问题),甚至可能 SQL 注入。修复:
DECLARE
v_table_name text;
v_column_name text;
v_id_lock_usr integer; -- guessing the data type
i integer;
BEGIN
SELECT nm_table_name, replace(nm_table_name, 'CDB_', 'ID_')
INTO strict v_table_name, v_column_name
FROM m_entity e
WHERE id = 12;
EXECUTE format('UPDATE %I SET id_lock_usr = null, dt_lock = null
WHERE %I = RETURNING id_lock_usr'
, v_table_name,
, v_column_name)
INTO v_id_lock_usr; -- to store the *single* result from RETURNING
GET DIAGNOSTICS i = ROW_COUNT;
IF i > 0 THEN
-- do something
END IF;
END
注意 %I
而不是 %s
。
在您的情况下,如果您的查询返回的 id_lock_usr
是 NOT NULL
(可靠),您可能只是直接测试结果:
IF v_id_lock_usr IS NOT NULL ...
并且您可能希望对 table 名称进行模式限定以避免歧义。但是你必须将 schema_name.table_name
作为两个单独的标识符转义 ..
相关:
- Are PostgreSQL column names case-sensitive?
- Define table and column names as arguments in a plpgsql function?
- Table name as a PostgreSQL function parameter