2017-08-01 20 views
0

我試圖運行此腳本替代參數,但它不斷拋出語法errors.Is有什麼錯的syntax.Also什麼是調用這個function.I需要正確的方法一個輸出告訴我更新語句已成功執行。我嘗試「選擇函數名(schema_name.TABLE_NAME);」讓我補充一點,我是一個初學者,願意接受任何形式的反饋。如有必要也會提供更多細節。如何運行PostgreSQL中的多個更新語句

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列不存在或該功能不存在 即使我只是宣佈它。

+2

提供語法錯誤(即使它們對你沒有意義)將會有所幫助。 您提供的代碼是不完整的,這使得它很難甚至開始提出改進建議。 –

+0

更新值後有額外的單引號。 – Mokadillion

+0

成功執行是什麼意思?沒有錯誤?受影響的行> 0? –

回答

0

要使用單引號選址不變裏面,你必須通過他們加倍逃避他們。

而不是

' SET column1='0'' 

你得寫

' SET column1=''0''' 
+0

我做了這個改變 – user8398482

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 *結構
  • 做法是好的,但閱讀的概念是珍貴

在您的文章select function_name(schema_name.TABLE_NAME);回函。 LD不行的,因爲你用schema_name.TABLE_NAME沒有引號,但即使你把它們放在你的函數是脆弱的 - 如果你運行select function_name(';drop sometable;--');會發生什麼事..

0

您試圖通過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')