【问题标题】:SAS to PostgreSQL(PADB) code - summing field if they existsSAS 到 PostgreSQL(PADB) 代码 - 求和字段(如果存在)
【发布时间】:2018-08-29 14:28:17
【问题描述】:

我遇到了来自 SAS 的一段代码的挑战,我需要将其转换为 SQL。 通常我在这方面非常擅长,但并非如此,我正面临新的挑战,到目前为止,我解决它的所有想法都失败了,而且我没有找到正确的方法。

我需要能够为此请求动态选取字段,例如,如果字段的名称中有特定模式,我需要对这些字段求和。

我的 PostgreSQL 版本是 8.0.2,PADB 5.3.3.1 78560

所以表格可能有也可能没有像bas_txn_03cibc_vcl 这样的字段。

我写了一个函数,当在 information_schema 表中找不到该字段时应该输出' ' as bas_txn_03cibc_vcl,如果找到则使用bas_txn_03cibc_vcl

但是当我执行命令时,我得到了 UDF 不能用于 PADB 表的错误。

“错误:XX000:用户定义的 SQL 语言函数“check_if_field_exists(字符变化,字符变化,字符变化)”不能在引用 PADB 表的查询中使用。”

现在我正在使用存储过程构建一种新方法,但它会限制用例。关于如何动态选择字段的任何其他想法?

功能:

CREATE OR REPLACE FUNCTION check_if_field_exists(_schm text, _tbl text, _field text)
RETURNS text AS
$BODY$
DECLARE 
    _output_ text:=  '' as _field;
BEGIN 
EXECUTE   'SELECT column_name into : _output_ FROM rdwaeprd.information_schema.columns 
where table_schema='''|| _schm||'''   
and table_name='''|| _tbl||'''   
and column_name='''|| _field||'''   
order by table_name,column_name;';  
RETURN _output_;
END
$BODY$
LANGUAGE PLPGSQL;

然后我会这样使用它

select indiv_id,ae_psamson.check_if_field_exists('ae_psamson','activ_cc', 'tot_txn_03AMX_AMXE') ,tot_txn_03AMX_AMXD
from activ_cc
group by indiv_id,tot_txn_03AMX_AMXD;

函数将返回 '' 作为 tot_txn_03AMX_AMXE 或简单地返回 tot_txn_03AMX_AMXE.... 的想法是,如果字段不存在,则使查询不返回错误。

就像我说的那样,我需要一个新的功能或方法,因为这个不起作用......

【问题讨论】:

  • PostgreSQL 8.0.2 版本太旧了
  • Postgres 8.0 已经使用out of support 8 年了。你不应该再使用它了。 现在计划升级到受支持和维护的版本(例如 10)
  • 您可以至少将函数添加到您的问题中(pg-8-0 的手册页仍然可用),甚至可以解释 PADB 表是什么。
  • PADB 表是当前 DMBS 创建的标准表。该功能现在已添加到 Q 中,但由于该策略不起作用,我不确定它将如何提供帮助。我需要一个新策略,或者一个存在的函数,但我不知道它会检查一个字段是否存在,如果不存在,则执行其他操作......你知道有点像 drop table if exists...
  • 你不需要动态SQL或plpgsql;您可以直接查询目录,就像任何其他表一样。

标签: postgresql postgresql-8.0


【解决方案1】:

我设法制作了一个让它工作的函数! 基本上问题之一是该信息架构在 UDF 中使用了不受支持的功能。 此解决方案效果很好:

CREATE OR REPLACE FUNCTION check_if_field_exists(_schm text, _tbl text, _field text)
RETURNS varchar(55)  AS
$BODY$
DECLARE 
    _output_ varchar(55) :=' 0 as '|| _field;
--  name := (SELECT t.name from test_table t where t.id = x);
BEGIN 
EXECUTE  'drop table if exists col_name';
EXECUTE  'create table col_name as SELECT att.attname::character varying(128) AS colname   
FROM pg_class cl, pg_namespace ns, pg_attribute att 
WHERE cl.relnamespace = ns.oid AND cl.oid = att.attrelid AND ns.nspname='''|| _schm ||''' 
and cl.relname='''|| _tbl ||''' 
and colname like '''|| _field||''''; -- INTO _output_;
select colname from col_name into _output_ ;  
if _output_ is null then 
_output_  :=' 0 as '|| _field;
end if;
RETURN _output_  ;
END 
$BODY$
LANGUAGE PLPGSQL;

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-05-04
    • 2013-05-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多