Table name alias in netezza - sql

I use the following commands in netezza SQL to define table name alias while running a query through command line NZSQL
\set catgtable 'table_a'
\echo table name is :catgtable
and I use the table name alias catgtable wherever required as in:
select *
from :catgtable where col1 is not NULL
My problem is how to use the alias name in these 2 situations:
select ':catgtable' as table_name, col1,col2
from table_x
This gives me an error, since it requires the actual table name.
select table_name, column_name
from _v_sys_columns
where table_name = ':catgtable' and column_name like '%merch_cat_%'
Here again the alias: catgtable doesn't work and it requires the actual table name.
Let me know if there is a workaround.

When you want to use the contents of a variable as a literal in nzsql you need to include an additional set of single quotes, escaped with backslashes, around the literal text when you set the variable.
TESTDB.ADMIN(ADMIN)=> \set tvar '\'BLAH\''
TESTDB.ADMIN(ADMIN)=> select :tvar col_alias;
COL_ALIAS
-----------
BLAH
(1 row)

Related

how can I print details (table name, column name, data type) of each column/table in my db2 database?

In my previous question Mark suggested a good answer for displaying count on every table in my database. I would like to expand this procedure and - instead of counts - display the specific info (TABLE_SCHEMA, TABLE_NAME, COLUMN_NAME, DATA_TYPE) about each column in the database.
I so far have the following command:
--#SET TERMINATOR #
CREATE OR REPLACE FUNCTION EXPORT_SCHEMAS()
RETURNS TABLE (P_TABSCHEMA VARCHAR(128), P_TABNAME VARCHAR(128), P_COLUM_NNAME VARCHAR(128), P_DATA_TYPE VARCHAR(128))
BEGIN
DECLARE L_STMT VARCHAR(256);
DECLARE L_ROWS VARCHAR(256);
FOR V1 AS
SELECT TABSCHEMA, TABNAME
FROM SYSCAT.TABLES
WHERE TYPE = 'T'
ORDER BY 1,2
DO
SET L_STMT = 'SET ? = (SELECT TABLE_SCHEMA, TABLE_NAME, COLUMN_NAME, DATA_TYPE FROM SYSIBM.COLUMNS where TABLE_NAME = "'||V1.TABNAME||'" AND TABLE_SCHEMA = "'||V1.TABSCHEMA||'")';
PREPARE S FROM L_STMT;
EXECUTE S INTO L_ROWS;
PIPE(L_ROWS);
END FOR;
RETURN;
END#
SELECT * FROM TABLE(EXPORT_SCHEMAS())#
but now when I run it:
db2 -ntd~ -f export_schemas.sql > dump.csv
I'm getting the error:
DB21034E The command was processed as an SQL statement because it was not a
valid Command Line Processor command. During SQL processing it returned:
SQL20019N The result type returned from the function body cannot be assigned
to the data type defined in the RETURNS clause. LINE NUMBER=17.
SQLSTATE=42866
Could you please help me and let me know what is wrong here and how could I fix it? Thanks!
If you use Db2 for LUW, then you shouldn't use SYSIBM schema in your queries on the system catalog. Use SYSCAT instead.
You don't have to use any functions to get what you want here. Use the following query instead:
SELECT TABSCHEMA, TABNAME, COLNAME, TYPENAME
FROM SYSCAT.COLUMNS
ORDER BY TABSCHEMA, TABNAME, COLNO;
As for your routine. There is a number of errors in the text.
1) if you want to assign multiple values with SET statement, you must use the corresponding number of parameter markers in the statement:
SET (?, ..., ?) = (SELECT COL1, ..., COLn FROM ...);
PREPARE S FROM L_STMT;
EXECUTE S INTO L_V1, ..., L_Vn;
2) RETURNS TABLE (...) and PIPE(...) must have the same number of columns
You could directly query the tables SYSCAT.COLUMNS and SYSCAT.TABLES. The following returns the table schema and name followed by column name and their type. Column info is sorted by the column order:
select t.tabschema, t.tabname, c.colname, c.typename, c.colno
from syscat.columns c, syscat.tables t
where t.type='T' and t.tabname=c.tabname and t.tabschema=c.tabschema
order by 1,2,c.colno
BTW: Db2 has a tool db2look to export schema information.

Dropping column with quotation marks in column name

I added a column using following commands (I used quotation marks so that N is in upper case in my column name)
ALTER TABLE new_table
ADD “Name” VARCHAR(50);
However, I see "nam" column in my table now after running that command.
How can I drop that column?
ALTER TABLE new_table
DROP COLUMN "Name";
I get following error:
ERROR: column "name" of relation "new_table" does not exist
The following statement causes this error:
ALTER TABLE new_table
DROP COLUMN "Name";
seems you are not using double quote " in first query bus some others quotes try suing the same chars “”
ALTER TABLE new_table DROP COLUMN “Name”;
Check how Postgres is storing the column name when you are using a double quote in column name:
select table_name, column_name from information_schema.columns where
table_name='tab1';
Also, you may view the same when you execute a select statement:
select * from table;
Copy the same column name text in your alter statement. Here is the sample column name with both kind of double quotes in PostgreSQL:
create table tab1(data varchar(30));
alter table tab1 ADD “Name1” varchar(50);
alter table tab1 ADD "Name2" varchar(50);
select *from tab1;
select table_name, column_name from information_schema.columns where table_name='tab1';
alter table tab1 drop column “Name1”;
alter table tab1 drop column "Name2";
table_name column_name
tab1 data
tab1 “name1”
tab1 Name2
Here is the link to the fiddle
Note: Avoid using a double quote in the table name, column, etc. In case you use you have to ensure that the same names are specified in all queries.
Edit:
It's simple. If you use "Name" (not same as “Name”, notice quote angle) in the column name then you have to refer the column as "Name". In case “Name” is used then you have to refer by “Name”. The quotes need to match.
Another observation is when "Name" used as column name it makes the column name as Name (N uppercase) as opposed to all lowercase column names by default in the database but needs to be referred as "Name".

Oracle SQL using variable in Select or For-Loop

I need to verify data across several tables. In essence i want to write a loop for the below statement with all of the fields in a given table.
sql> select fld1, count(*)
from table1
group by fld1
;
I'm thinking that I need to create at least 2 variables. The first variable would be prompted to provide the table name.
The second var would be something based on the result of :
select column_name from user_tab_col_statistics where table_name = table_variable
Should I also create a temp table and select into that?
As per my understanding you can store the values in the temporary table.
1.Fetch Table Name & Column Name put in Variable Var_Table_name,Var_Col
select Var_Col, count(*) into Var1,Var2 from Var_Table group by fld1 ;
for all the tables columns .You can create a temporary table and insert the values as mentioned below and store in the temp table .
1.Var_Table_name
2.Var_Col
3.Var1
4.Var2
PL/SQL does not prompt. On the other hand SQL*Plus will prompt for substitution variables. See following example.
MPOWEL01> #stack
MPOWEL01>
MPOWEL01> select table_name, column_name from user_tab_col_statistics where table_name = upper('&tbl_nm')
2 order by column_name;
Enter value for tbl_nm: marktest
old 1: select table_name, column_name from user_tab_col_statistics where table_name = upper('&tbl_nm')
new 1: select table_name, column_name from user_tab_col_statistics where table_name = upper('marktest')
TABLE_NAME COLUMN_NAME
------------------------------ ------------------------------
MARKTEST FLD1
MARKTEST FLD2
MARKTEST FLD3
MARKTEST FLD4
MPOWEL01>
set verify off will eliminate the substitution message line from the output.
In PL/SQL you either need to SELECT INTO variables or use a cursor.
I think you might just be able to use SQL to generate the SELECT statements you want to run, but what exactly do you mean by 'verify data'? Verify how? Using what standard?

Variable in sql file with single quote

SELECT SWAP_PARTITIONS_BETWEEN_TABLES
(':SCHEMA_NAME.:TABLE_NAME',:PARTITION_KEY,:PARTITION_KEY,
':SCHEMA_NAME.:TABLE_NAME');
This is a vertica query in sql file
:SCHEMA_NAME and :TABLE_NAME in sql file is not getting replaced by the argument passed probably because of single quotes
Try this:
\set source '''src_schema.src_table'''
\set target '''tgt_schema.tgt_table'''
SELECT SWAP_PARTITIONS_BETWEEN_TABLES
(:source,:PARTITION_KEY,:PARTITION_KEY,:target);
If you want to use different variables for SCHEMA and TABLE, you can:
\set schema '''myschema'''
\set table '''mytable'''
And then:
SELECT SWAP_PARTITIONS_BETWEEN_TABLES
(:schema||'.'||:table,:PARTITION_KEY,...);

Filter in select where values start with NIR_

I am trying to filter my result set to only return values which start with NIR_.
My SQL statement to do so is as follows
select * from run where name like %NIR_%
The result set also includes names like
NIRMeta_Invalid
NIRMeta_Position
I am not sure what I am doing wrong. I only need to select names which start with NIR_.
You need to escape the underscore in your LIKE pattern if you want it to be treated as a literal.
In SQL Server:
select * from run where name like 'NIR[_]%'
In MySQL and Oracle:
select * from run where name like 'NIR\_%'
If you want names that only start with NIR, then remove the first wildcard in the like pattern:
where name like 'NIR_%'
Note that _ is also a wildcard, so you probably want:
where name like 'NIR\_%'
You can use ESCAPE option to achieve this.
SELECT * FROM run WHERE name LIKE 'NIR#_%' ESCAPE '#'
Sample execution with the given data:
DECLARE #Run TABLE (name VARCHAR (100));
INSERT INTO #Run (name) VALUES
('NIR_MA'), ('NIR_RUN'), ('NIRMeta_Invalid'), ('NIRMeta_Position');
SELECT * FROM #Run WHERE name LIKE 'NIR#_%' ESCAPE '#'
Result:
name
-----
NIR_MA
NIR_RUN