我有一个名为L0
的表,它创建为:
create table L0 (
name varchar,
number varchar,
address varchar
);
L0
中显示的所有列的数据类型为varchar
,
我有另一个表L1
,它创建为:
create table L1 (
name varchar,
number int,
address char
);
我想通过传递表名将L0
表的数据类型转换为与L1
表相同。
我希望最终查询看起来像这样:
select cast(name as varchar), cast(number as int), cast(address as char) from L0
minus
select * from L1:
这样做的方法是什么?
答案 0 :(得分:0)
如果你在Netezza中安装了group_concat UDA,那么你可以使用columns
元数据视图获得所需的输出
create table L0 (
name varchar(20),
number varchar(10),
address varchar(50)
);
create table L1 (
name varchar(50),
number int,
address char(20)
);
查询:
SELECT 'select ' || system..group_concat('cast (' || a.column_name || ' as ' || b.data_type || ')') || ' from ' || a.table_name || ' minus select ' || system..group_concat(b.column_name) || ' from ' || b.table_name || ' ;'
FROM columns a
,columns b
WHERE a.column_name = b.column_name
AND a.table_name = 'L0'
AND b.table_name = 'L1'
AND a.table_catalog = 'TEST' --- this is the current database name
GROUP BY a.table_name
,b.table_name;
<强>输出:强>
SELECT cast(ADDRESS AS CHARACTER(20))
,cast(NAME AS CHARACTER VARYING(50))
,cast(NUMBER AS INTEGER)
FROM L0 minus
SELECT ADDRESS
,NAME
,NUMBER
FROM L1;
修改强> 使用存储过程
的替代方法CREATE OR REPLACE PROCEDURE GRP_CONCAT(varchar(50),varchar(50))
RETURNS VARCHAR(ANY)
EXECUTE AS OWNER
LANGUAGE NZPLSQL AS
BEGIN_PROC
DECLARE
TABLE_NAME1 ALIAS FOR $1;
TABLE_NAME2 ALIAS for $2;
return_text varchar(10000) := 'SELECT';
x record;
BEGIN
FOR x IN select a.column_name as colname,b.data_type datatype
FROM columns a
,columns b
WHERE a.column_name = b.column_name
AND a.table_name = TABLE_NAME1
AND b.table_name = TABLE_NAME2
order by b.ordinal_position
LOOP
return_text := return_text || ' CAST ('||x.colname ||' as '||x.datatype||') , ';
end loop;
return_text := trim(return_text,' , ')||' FROM '||TABLE_NAME1 || ' minus select * from '||TABLE_NAME2||';';
return return_text;
EXCEPTION WHEN OTHERS THEN
RAISE NOTICE 'ERROR: %', SQLERRM;
RETURN 1;
END;
END_PROC;
输出
致电GRP_CONCAT(&#39; L0&#39;,&#39; L1&#39;);
SELECT CAST(NAME AS CHARACTER VARYING(50))
,CAST(NUMBER AS INTEGER)
,CAST(ADDRESS AS CHARACTER(20))
FROM L0 minus
SELECT *
FROM L1;