我遇到一个问题,当我尝试直接按名称引用参数时,我会在调用函数后返回文字值。任何人都可以帮我解决如何在这里使用参数值的问题吗?
CREATE OR REPLACE FUNCTION dbo.reset_sequence(
tablename text,
columnname text,
sequence_name text)
RETURNS void AS
$BODY$
DECLARE
BEGIN
IF( (SELECT MAX( columnname ) ) < (SELECT min_value FROM dbo.tablename) )
THEN
-- EXECUTE 'SELECT setval( ' || sequence_name || ', (SELECT min_value FROM dbo.' || sequence_name ||')';
ELSE
-- EXECUTE 'SELECT setval( ' || sequence_name || ', ' || '(SELECT MAX("' || columnname || '") FROM dbo."' || tablename || '")' || '+1)';
END IF;
END;
$BODY$
LANGUAGE plpgsql VOLATILE;
编辑:我遇到的问题更具体地与EXECUTE
命令之外的语法有关。另一种解决方案并没有真正帮助我。
在研究了另一个主题后,我正在尝试另一种解决方案,但仍然遇到问题。
CREATE OR REPLACE FUNCTION dbo.reset_sequence(
tablename text,
columnname text,
sequence_name text)
RETURNS void AS
$BODY$
DECLARE
_maxVal int;
_minVal int;
BEGIN
EXECUTE format('SELECT MAX( ''' || columnname || ''' ) FROM ' || schema_name || '."' || tablename || '"')
INTO _maxVal;
EXECUTE format('SELECT min_value FROM ' || schema_name || '."' || sequence_name || ''' ')
INTO _minVal;
IF( maxVal < _minVal)
THEN
-- EXECUTE 'SELECT setval( ' || sequence_name || ', (SELECT min_value FROM dbo.' || sequence_name ||')';
ELSE
-- EXECUTE 'SELECT setval( ' || sequence_name || ', ' || '(SELECT MAX("' || columnname || '") FROM dbo."' || tablename || '")' || '+1)';
END IF;
END;
$BODY$
LANGUAGE plpgsql VOLATILE;
关于它的语法有效,但是当我调用该函数时,我得到一个错误,它不能将EXECUTE
语句存储为整数,它似乎返回列的名称,而不是该列中的最大值。
答案 0 :(得分:1)
没有解释该函数应该做什么,代码是模糊的。据我了解,这是该功能的目的:
将给定模式中的给定序列重置为同一模式的给定表中给定列的最大值 - 或者如果它应该更大,则给定序列的最小值。 强>
尚不清楚架构dbo
是否也参与其中。将dbo
保留在循环中,此应工作:
CREATE OR REPLACE FUNCTION reset_sequence(
sch text, -- schema_name
tbl text, -- table_name
col text, -- column_name
seq text -- sequence_name -- all unquoted and case-SENSITIVE!
) RETURNS void AS
$func$
DECLARE
_max_val int;
_min_val int;
BEGIN
EXECUTE format('SELECT MAX(%I) FROM %I.%I', col, sch, tbl)
INTO _max_val;
EXECUTE format('SELECT min_value FROM %I.%I', sch, seq)
INTO _min_val;
IF _max_val < _min_val THEN
EXECUTE format($$SELECT setval('%1$I.%2$I', min_value, false) FROM dbo.%2$I;$$
, sch, seq);
ELSE
EXECUTE format($$SELECT setval('%I.%I', max(%I)) FROM dbo.%I;$$
, sch, seq, col, tbl);
END IF;
END
$func$ LANGUAGE plpgsql;
可以简化为:
CREATE OR REPLACE FUNCTION pg_temp.reset_sequence(sch text, tbl text, col text, seq text)
RETURNS void AS
$func$
DECLARE
_found bool;
BEGIN
EXECUTE format('SELECT true FROM %1$I.%2$I
HAVING MAX(%3$I) < (SELECT min_value FROM %1$I.%4$I)'
, sch, tbl, col, seq)
INTO _found;
IF _found THEN
EXECUTE format($$SELECT setval('%1$I.%2$I', min_value, false) FROM dbo.%2$I;$$
, sch, seq);
ELSE
EXECUTE format($$SELECT setval('%I.%I', max(%I)) FROM dbo.%I;$$
, sch, seq, col, tbl);
END IF;
END
$func$ LANGUAGE plpgsql;
如果使用 只是我怀疑的拼写错误,更简单:dbo
CREATE OR REPLACE FUNCTION pg_temp.reset_sequence(sch text, tbl text, col text, seq text)
RETURNS void AS
$func$
BEGIN
EXECUTE format($$
SELECT setval('%1$I.%4$I', GREATEST(s.min, t.max + 1), false) -- now we need + 1
FROM (SELECT MAX(%3$I) FROM %1$I.%2$I) t(max)
, (SELECT min_value FROM %1$I.%4$I) s(min)
$$, sch, tbl, col, seq);
END
$func$ LANGUAGE plpgsql;
您正在以无意义的方式将format()
与纯字符串连接混合。在继续之前,请务必read the manual on format()
。
变量schema_name
未定义。我添加了另一个函数参数来传递它。
您在 奇数 中使用了最后两个dbo
调用中的架构setval()
。此外,"dbo"
是SQL Server的典型标识符,但不是Postgres中的标识符。可能是另一个错误还是故意的?
变量maxVal
未定义。可能应该是_maxVal
。我在简化版中完全删除了该变量。
+ 1
您不需要setval()
,因为默认情况下,返回的下一个值会增加。 Example in the manual:
SELECT setval('foo', 42); -- Next nextval will return 43
另一方面,如果您想从序列的最开始处开始,请使用:
SELECT setval('my_sequence', min_value, false)
只有运行查询才能干净:
SELECT setval('my_sequence', min_value) FROM other_sequence;
..因为SEQUENCE
的表格保证完全 1行。
答案 1 :(得分:0)
如果先使用EXECUTE .. INTO
将它们存储到临时值中,则可以使用EXECUTE
语句中IF
语句的结果。例如:
DECLARE
max_column_value int;
BEGIN
EXECUTE 'SELECT MAX(' || columnname || ') FROM dbo."' || tablename || '"'
INTO max_column_value;
IF max_column_value < 1000 THEN
...
如果columnname
为'col'
且tablename
为'tbl'
,则应该相当于:
IF (SELECT MAX(col) FROM dbo."tbl") < 100 THEN