我尝试使用参数运行此脚本,但它不断抛出语法错误。语法有什么问题。还有什么是调用此函数的正确方法。我需要一个输出告诉我更新语句被成功执行了。我尝试了“select 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列不存在或该函数不存在 即使我刚宣布它。
答案 0 :(得分:0)
要在选址常量中使用单引号,必须通过将它们加倍来对它们进行转义。
而不是
' SET column1='0''
你必须写
' SET column1=''0'''
答案 1 :(得分: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 而没有引号,但即使您放置它们,您的功能也很容易受到影响 - 如果您运行{会发生什么? {1}}?..
答案 2 :(得分: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')