[英]how to reference a schema variable in plpgsql
I am trying to learn plpgsql code to automate some data cleaning in a database. 我正在尝试学习plpgsql代码以自动执行数据库中的某些数据清理。
My current task is to replace all of '999' values in numeric fields with 'NaN'. 我当前的任务是将数字字段中的所有“ 999”值替换为“ NaN”。 What I am trying to do is: 1) find all columns in a schema that are numeric 2) loop through these and use 'update/replace' 我正在尝试做的是:1)找到数字模式中的所有列2)遍历这些列并使用“更新/替换”
My code is below. 我的代码如下。 I think my main problem is finding out how to reference the schema.table in the update statement (but I am sure there are other things I have not done too well). 我认为我的主要问题是找出如何在update语句中引用schema.table(但我确信还有其他事情我做得还不够好)。
The error that I am getting is that the relation is not recognised. 我得到的错误是该关系未被识别。 Any assistance would be appreciated 任何援助将不胜感激
Becky 贝基
CREATE OR REPLACE FUNCTION household.nodata_replace(schemanm text)
RETURNS VOID as $$
DECLARE
cname text;
tname text;
BEGIN
--FOR col IN
for cname,tname in SELECT column_name::text,table_name::text FROM information_schema.columns
where table_schema = schemanm and data_type in ('integer','double precision')
LOOP
RAISE NOTICE 'cname is: % from %', cname, tname;
EXECUTE 'update '||schemanm::regclass||'.' ||tname::regclass||
' set ' || quote_ident(cname) ||' = replace(' || quote_ident(cname) ||', 999, NaN);';
END LOOP;
END;
$$
LANGUAGE plpgsql;
I would rather use format()
for this. 我宁愿为此使用format()
。 The placeholder %I
takes care of properly quoting identifiers if needed. 占位符%I
需要时会正确引用标识符。
replace()
is for string manipulation not for replacing numbers. replace()
用于字符串操作,而不用于替换数字。 To assign the value NaN use set xxx = 'NaN'
but you cannot do this for an integer
value. 要分配值NaN,请使用set xxx = 'NaN'
但是您不能对integer
数值执行此操作。 Integers do not support NaN
整数不支持NaN
So your dynamic SQL boils down to: 因此,您的动态SQL归结为:
execute format('update %I.%I set %I = ''NaN'' where %I = 999, schemanm, tname, cname, cname);
But you will need to change your where clause to not include integer
columns. 但是您将需要更改where子句以不包括integer
列。 You probably want to include numeric
and real
as well: 您可能还希望包括numeric
和real
:
and data_type in ('numeric','double precision', 'real')
If you just want to mark the "absence of information", I would rather store null
in those columns. 如果您只想标记“缺少信息”,我宁愿在这些列中存储null
。 In that case you don't need to distinguish between the different data types: 在这种情况下,您无需区分不同的数据类型:
execute format('update %I.%I set %I = null where %I = 999, schemanm, tname, cname, cname);
try to rework your query like following: 尝试重新整理您的查询,如下所示:
EXECUTE 'update '|| (schemanm||'.'||tname)::regclass ||' set ' || quote_ident(cname) ||' = ''NaN'' WHERE '|| quote_ident(cname) ||' = 999;'
because casting to regclass
is trying to search within registered relations. 因为强制转换为regclass
试图在已注册的关系中进行搜索。 and schema is not relation. 与架构无关。
or you can 或者你可以
EXECUTE 'update '|| quote_ident(schemanm)||'.'||quote_ident(tname) ||' set ' || quote_ident(cname) ||' = ''NaN'' WHERE '|| quote_ident(cname) ||' = 999;'
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.