[英]How to run multiple insert statements in a transaction in postgresql?
[英]how to run multiple updated statements in postgresql
我試圖使用適當的參數運行此腳本,但它始終拋出語法錯誤。語法是否有問題。調用此函數的正確方法是什么。我需要一個輸出來告訴我update語句已成功執行。 我嘗試了“選擇function_name(schema_name.TABLE_NAME);”。讓我補充一下,我是一個初學者,可以接受任何反饋。 如有必要,還將提供更多詳細信息。
CREATE OR REPLACE FUNCTION function_name (TABLE_NAME IN character varying)
RETURNS text AS $SQLQuery$
DECLARE SQLQuery text;
BEGIN
SQLQuery =
' UPDATE '|| TABLE_NAME || ' SET column1=''0''
WHERE column1 is null;' ||
' UPDATE '|| TABLE_NAME || ' SET column2='value'
WHERE column2=''different value'';' ||
--multiple update statements later
Execute SQLQuery;
Return SQLQuery;
END;
$SQLQuery$
LANGUAGE plpgsql;
更新:這是我調用測試函數時遇到的錯誤
ERROR: missing FROM-clause entry for table "schema_name" LINE 2: select test_function(schema_name.TABLE_NAME); ^ ********** Error ********** ERROR: missing FROM-clause entry for table "schema_name" SQL state: 42P01
它是作為表讀取函數嗎? 我還收到語法錯誤,說EXECUTE列不存在,或者即使我剛剛聲明了該函數也不存在。
要在選址常量中使用單引號,必須通過將它們加倍來對其進行轉義。
代替
' SET column1='0''
你必須寫
' SET column1=''0'''
像:
CREATE OR REPLACE FUNCTION function_name (schema_name text,TABLE_NAME IN character varying)
RETURNS text AS $SQLQuery$
DECLARE
c int;
rtn text :='';
BEGIN
execute format(' UPDATE %I.%I SET column1=''0'' WHERE column1 is null;',schema_name,TABLE_NAME);
get diagnostics c = row_count;
raise info '%', 'affected: '||c;
rtn = rtn + 'affected: '||c||chr(10);
--repeat above construct for multiple update statement
return rtn;
END;
$SQLQuery$
LANGUAGE plpgsql;
並提供建議。 我像您一樣是新手,但是我學會了遵循一些規則,這些規則對我有幫助:
format
以避免sql注入 UPDATE
語句中-檢查輸出。如果要檢查結果行的使用,請使用UPDATE ... RETURNING *
構造。 在您的POST中select function_name(schema_name.TABLE_NAME);
將不起作用,因為您使用schema_name.TABLE_NAME不帶引號,但是即使您加上引號,您的函數也很容易受到攻擊-如果運行select function_name(';drop sometable;--');
會發生什么情況select function_name(';drop sometable;--');
?..
您正在嘗試傳遞SQL標識符,但是您的函數改為使用字符串作為參數。 您應該將其更改為: select test_function('schema_name.TABLE_NAME');
您可以在下面嘗試使用該功能作為您嘗試做的事情的基礎。
/* You need to split table and schema name
or you might get errors when using names that aren't lower case.
This: 'public.TEST1' would be translated to: "public.TEST1"
that is different table from public.test1
*/
CREATE OR REPLACE FUNCTION multi_update_stuff(schema_name varchar, table_name varchar)
/* We will return set of multiple columns. One possible method is to return table.
First column shows executed query, second if it returned no errors (true)
*/
RETURNS TABLE(SQLQuery text, result boolean)
AS $body$
DECLARE
/* Declare arroy of queries that we will iterate and execute later.
We use format() to build query from template and fill it with values.
%1$I can be described as "put first value here and treat it as object identifier"
%3$L can be described as "put third value here and treat it as SQL literal"
*/
SQLQueries text[] := array[
/* First query */
format('UPDATE %1$I.%2$I SET column1 = %3$L WHERE column1 is null;',
schema_name, table_name, '0'),
/* Second query */
format('UPDATE %1$I.%2$I SET column2 = %3$L WHERE column2 = %4$L;',
schema_name, table_name, 'value', 'different value'),
/* Third query, to see error free result */
'SELECT 1'];
BEGIN
/* Iterate our array */
FOREACH SQLQuery IN ARRAY SQLQueries
LOOP
/* Start transaction block */
BEGIN
EXECUTE SQLQuery;
result := true;
/* Catch error if any */
EXCEPTION
WHEN others THEN
result := false;
END;
/* Return row with whatever is assigned to variables listed in RETURNS.
In this case SQLQuery was already assigned by FOREACH.
*/
RETURN NEXT;
END LOOP;
END;
$body$
LANGUAGE plpgsql;
SELECT * FROM multi_update_stuff('schema_name', 'TABLE_NAME')
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.