簡體   English   中英

如何在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;

並提供建議。 我像您一樣是新手,但是我學會了遵循一些規則,這些規則對我有幫助:

  • 具有動態sql使用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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM