无法在 PostgreSQL 中创建存储过程:“$$”处或附近未终止的美元引号字符串
Unable to create stored procedure in PostgreSQL: unterminated dollar-quoted string at or near "$$
我快疯了。在SQL服务器中,创建存储过程非常简单。有一个简单的结构,您定义它并创建它。完毕。然而,在 Postgres 中,我看到了创建函数或存储过程的语法的许多变体,而我还没有能够创建一个。我总是出错。总是。关于我在网上试过的任何例子。
以下示例失败并出现此错误:
[Sep 3, 2020 12:26 PM] 42601: unterminated dollar-quoted string at or near "$$ DECLARE _schemaname text; _tablename text; _key text; _value text; _columns text[]; _values text[]; BEGIN SELECT pg_namespace.nspname, pg_class.relname INTO STRICT _schemaname, _tablename FROM pg_class JOIN pg_namespace ON (pg_namespace.oid = pg_class.relnamespace) WHERE pg_class.oid = ; FOR _key IN SELECT columns.column_name FROM information_schema.columns WHERE columns.table_schema = _schemaname AND columns.table_name = _tablename ORDER BY columns.ordinal_position LOOP EXECUTE format($s$SELECT format('%%L', ((()::%s).%I))$s$, , _key) USING INTO STRICT _value"
我不知道如何解决这个问题。我做了一些搜索,并尝试了将脚本顶部和底部的 $$ 更改为 $BODY$ 的建议,但它因相同的错误而失败。我做错了什么?
这是另一个网站上定义的存储过程。
CREATE OR REPLACE FUNCTION create_insert_statement(regclass, anyelement) RETURNS text
LANGUAGE plpgsql
AS $$
DECLARE
_schemaname text;
_tablename text;
_key text;
_value text;
_columns text[];
_values text[];
BEGIN
SELECT pg_namespace.nspname, pg_class.relname
INTO STRICT _schemaname, _tablename
FROM pg_class
JOIN pg_namespace
ON (pg_namespace.oid = pg_class.relnamespace)
WHERE pg_class.oid = ;
FOR _key IN
SELECT columns.column_name
FROM information_schema.columns
WHERE columns.table_schema = _schemaname
AND columns.table_name = _tablename
ORDER BY columns.ordinal_position
LOOP
EXECUTE format($s$SELECT format('%%L', ((()::%s).%I))$s$, , _key) USING INTO STRICT _value;
_columns := _columns || _key;
_values := _values || _value;
END LOOP;
RETURN format('INSERT INTO %s (%s) VALUES (%s)', , array_to_string(_columns, ','), array_to_string(_values, ','));
END;
$$;
你用错了数据库客户端,因为功能没问题。
您的客户可能不喜欢美元报价,并认为 SQL 语句以函数体中的第一个分号结束。
您可以尽量避免使用美元引号,并酌情将单引号加倍或加倍,或者您可以使用更好的客户端软件。
您使用的是损坏的客户端,例如 HeidiSQL,它会在将您输入的文本传输到数据库之前破坏它。
我快疯了。在SQL服务器中,创建存储过程非常简单。有一个简单的结构,您定义它并创建它。完毕。然而,在 Postgres 中,我看到了创建函数或存储过程的语法的许多变体,而我还没有能够创建一个。我总是出错。总是。关于我在网上试过的任何例子。
以下示例失败并出现此错误:
[Sep 3, 2020 12:26 PM] 42601: unterminated dollar-quoted string at or near "$$ DECLARE _schemaname text; _tablename text; _key text; _value text; _columns text[]; _values text[]; BEGIN SELECT pg_namespace.nspname, pg_class.relname INTO STRICT _schemaname, _tablename FROM pg_class JOIN pg_namespace ON (pg_namespace.oid = pg_class.relnamespace) WHERE pg_class.oid = ; FOR _key IN SELECT columns.column_name FROM information_schema.columns WHERE columns.table_schema = _schemaname AND columns.table_name = _tablename ORDER BY columns.ordinal_position LOOP EXECUTE format($s$SELECT format('%%L', ((()::%s).%I))$s$, , _key) USING INTO STRICT _value"
我不知道如何解决这个问题。我做了一些搜索,并尝试了将脚本顶部和底部的 $$ 更改为 $BODY$ 的建议,但它因相同的错误而失败。我做错了什么?
这是另一个网站上定义的存储过程。
CREATE OR REPLACE FUNCTION create_insert_statement(regclass, anyelement) RETURNS text
LANGUAGE plpgsql
AS $$
DECLARE
_schemaname text;
_tablename text;
_key text;
_value text;
_columns text[];
_values text[];
BEGIN
SELECT pg_namespace.nspname, pg_class.relname
INTO STRICT _schemaname, _tablename
FROM pg_class
JOIN pg_namespace
ON (pg_namespace.oid = pg_class.relnamespace)
WHERE pg_class.oid = ;
FOR _key IN
SELECT columns.column_name
FROM information_schema.columns
WHERE columns.table_schema = _schemaname
AND columns.table_name = _tablename
ORDER BY columns.ordinal_position
LOOP
EXECUTE format($s$SELECT format('%%L', ((()::%s).%I))$s$, , _key) USING INTO STRICT _value;
_columns := _columns || _key;
_values := _values || _value;
END LOOP;
RETURN format('INSERT INTO %s (%s) VALUES (%s)', , array_to_string(_columns, ','), array_to_string(_values, ','));
END;
$$;
你用错了数据库客户端,因为功能没问题。
您的客户可能不喜欢美元报价,并认为 SQL 语句以函数体中的第一个分号结束。
您可以尽量避免使用美元引号,并酌情将单引号加倍或加倍,或者您可以使用更好的客户端软件。
您使用的是损坏的客户端,例如 HeidiSQL,它会在将您输入的文本传输到数据库之前破坏它。