WHERE条件在循环中使用数组中的信息
WHERE-condition using information from array in a loop
我想清除来自美国的地址数据。每当状态代码出现在前两个子字符串 (substring(address, 1, 2)) 中时,我想从列(地址)中估算状态代码。我构建了一个 foreach 循环,遍历美国各州的数组。但是,条件where = substring(address, 1, 2) = field
不起作用。field
在循环中使用:foreach field in array arr loop
。
整个代码如下所示:
create or replace function imp() RETURNS VOID AS $$
declare field varchar;
declare arr varchar[] := array['AL ', 'AK ', 'AZ ', 'AR ', 'CA ', 'CO ', 'CT ', 'DE ', 'DC ', 'FL ', 'GA ', 'HI ', 'ID ', 'IL ', 'IN ', 'IA ', 'KS ', 'KY ', 'LA ', 'ME ', 'MD ', 'MA ', 'MI ', 'MN ', 'MS ', 'MO ', 'MT ', 'NE ', 'NV ', 'NH ', 'NJ ', 'NM ', 'NY ', 'NC ', 'ND ', 'OH ', 'OK ', 'OR ', 'PA ', 'RI ', 'SC ', 'SD ', 'TN ', 'TX ', 'UT ', 'VT ', 'VA ', 'WA ', 'WV ', 'WI ', 'WY '];
begin
foreach field in array arr LOOP
update DE_inventor t1 set address_=t2.address_ from (
select
concat(address_, ' ', field)
as address_, pat_no, inventor
from DE_inventor
where ctry_code_inv = 'US' and substring(address, 1, 2)= field
) as t2
where t1.pat_no = t2.pat_no and t1.inventor = t2.inventor;
END LOOP;
RETURN;
END;
$$ language 'plpgsql';
select imp()
;
该循环在 concat(address_, ' ', field)
中运行良好(也在另一个过程中进行了测试和使用),但在 where 条件下则不然。
有谁知道为什么以及可以做什么?
在我看来,你的数组元素中有额外的 space:
declare arr varchar[] := array['AL ', 'AK ', 'AZ ',
^ ^ ^ those
正在阻止这一切成为现实:
substring(address, 1, 2)= field
substring (x, 1, 2) 永远是两个字符,永远不会匹配数组元素是三个字符的字段。
所以首先,你能去掉那些多余的 space 试试吗?
create or replace function imp() RETURNS VOID AS $$
declare
field varchar;
arr varchar[] := array['AL', 'AK', 'AZ', ... 'WY'];
begin
其次——您能否将状态加载到 table 中并使用它而不是数组?根据您的工作,它可能会不止一次派上用场。
第三,如果 inventor
和 pat_no
是您 table 的主键,那么我认为单个更新语句可能比 function/loop 更有效:
update de_inventor
set address_ = address_ || ' ' || left (address, 1, 2)
where
ctry_code_inv = 'US' and
left (address, 2) in ('AL', 'AK', 'AZ', 'AR' .. 'WY')
如果这些不是主键,那么您的更新语句可能会产生意想不到的后果,但我不确定。
无论哪种方式都值得深思。
您不需要为此更新使用循环或 plpgsql 代码,因为简单的 SQL 语句即可完成工作:
update de_inventor
set address_ = concat(address_, ' ', substring(address, 1, 2))
where ctry_code_inv = 'US'
and substring(address, 1, 2) in ('AL', 'AK', 'WY'); -- list of all state codes here
在这种情况下,SQL 方法比函数中的循环更有效、更简单。
我想清除来自美国的地址数据。每当状态代码出现在前两个子字符串 (substring(address, 1, 2)) 中时,我想从列(地址)中估算状态代码。我构建了一个 foreach 循环,遍历美国各州的数组。但是,条件where = substring(address, 1, 2) = field
不起作用。field
在循环中使用:foreach field in array arr loop
。
整个代码如下所示:
create or replace function imp() RETURNS VOID AS $$
declare field varchar;
declare arr varchar[] := array['AL ', 'AK ', 'AZ ', 'AR ', 'CA ', 'CO ', 'CT ', 'DE ', 'DC ', 'FL ', 'GA ', 'HI ', 'ID ', 'IL ', 'IN ', 'IA ', 'KS ', 'KY ', 'LA ', 'ME ', 'MD ', 'MA ', 'MI ', 'MN ', 'MS ', 'MO ', 'MT ', 'NE ', 'NV ', 'NH ', 'NJ ', 'NM ', 'NY ', 'NC ', 'ND ', 'OH ', 'OK ', 'OR ', 'PA ', 'RI ', 'SC ', 'SD ', 'TN ', 'TX ', 'UT ', 'VT ', 'VA ', 'WA ', 'WV ', 'WI ', 'WY '];
begin
foreach field in array arr LOOP
update DE_inventor t1 set address_=t2.address_ from (
select
concat(address_, ' ', field)
as address_, pat_no, inventor
from DE_inventor
where ctry_code_inv = 'US' and substring(address, 1, 2)= field
) as t2
where t1.pat_no = t2.pat_no and t1.inventor = t2.inventor;
END LOOP;
RETURN;
END;
$$ language 'plpgsql';
select imp()
;
该循环在 concat(address_, ' ', field)
中运行良好(也在另一个过程中进行了测试和使用),但在 where 条件下则不然。
有谁知道为什么以及可以做什么?
在我看来,你的数组元素中有额外的 space:
declare arr varchar[] := array['AL ', 'AK ', 'AZ ',
^ ^ ^ those
正在阻止这一切成为现实:
substring(address, 1, 2)= field
substring (x, 1, 2) 永远是两个字符,永远不会匹配数组元素是三个字符的字段。
所以首先,你能去掉那些多余的 space 试试吗?
create or replace function imp() RETURNS VOID AS $$
declare
field varchar;
arr varchar[] := array['AL', 'AK', 'AZ', ... 'WY'];
begin
其次——您能否将状态加载到 table 中并使用它而不是数组?根据您的工作,它可能会不止一次派上用场。
第三,如果 inventor
和 pat_no
是您 table 的主键,那么我认为单个更新语句可能比 function/loop 更有效:
update de_inventor
set address_ = address_ || ' ' || left (address, 1, 2)
where
ctry_code_inv = 'US' and
left (address, 2) in ('AL', 'AK', 'AZ', 'AR' .. 'WY')
如果这些不是主键,那么您的更新语句可能会产生意想不到的后果,但我不确定。
无论哪种方式都值得深思。
您不需要为此更新使用循环或 plpgsql 代码,因为简单的 SQL 语句即可完成工作:
update de_inventor
set address_ = concat(address_, ' ', substring(address, 1, 2))
where ctry_code_inv = 'US'
and substring(address, 1, 2) in ('AL', 'AK', 'WY'); -- list of all state codes here
在这种情况下,SQL 方法比函数中的循环更有效、更简单。