I have some very specific issue.
Target is to drop multiple tables in one schema that are older than 3 months and have certain prefix.
The difficulty is that I need to desing a script, that will generate drop statements automatically, so that I could shedule it to a crontab for daily execution.
Shortly, I need this two actions:
db2 "Select 'DROP TABLE ', tabname, ';' from syscat.tables where owner='DBUSER'" >> filename
db2 -tvf filename>log
been packed in a script that will generate the list of tables to be dropped and then drop those tables.
Actually, I have no idea how to do that... Please, give an advice.
Many thanks!
This script should provide a basis for you to move forward:
DROPFILE=/tmp/drop.$$.sql
echo ${DROPFILE}
db2 -o connect to pocdb
#
# Drop / Create tables for clean environment
#
for i in 0 1 2 3 4 5
do
db2 "drop table stkdrp.t${i}"
db2 "create table stkdrp.t${i} (f1 integer)"
done
#
# List tables, there should be six
#
db2 "select count(*) as tabcnt from syscat.tables where tabschema like 'STKDRP%' "
db2 "select tabschema, tabname from syscat.tables where tabschema like 'STKDRP%' order by tabname"
#
# Create the drop command file
#
db2 "select 'DROP TABLE ' || trim(tabschema) || '.' || trim(tabname) || ';' from syscat.tables where tabschema like 'STKDRP%'" 2>&1 | grep DROP > ${DROPFILE}
#
# Drop the tables
#
db2 -tvf ${DROPFILE}
#
# List tables, there should be zero (0)
#
db2 "select count(*) as tabcnt from syscat.tables where tabschema like 'STKDRP%' "
db2 "select tabschema, tabname from syscat.tables where tabschema like 'STKDRP%' order by tabname"
#
# Clean up the mess
#
rm -f ${DROPFILE}
db2 connect reset
db2 terminate
Results:
/tmp/drop.1607.sql
Database Connection Information
Database server = DB2/LINUXX8664 10.5.3
SQL authorization ID = DB2INST1
Local database alias = POCDB
DB21034E The command was processed as an SQL statement because it was not a
valid Command Line Processor command. During SQL processing it returned:
SQL0204N "STKDRP.T0" is an undefined name. SQLSTATE=42704
DB20000I The SQL command completed successfully.
DB21034E The command was processed as an SQL statement because it was not a
valid Command Line Processor command. During SQL processing it returned:
SQL0204N "STKDRP.T1" is an undefined name. SQLSTATE=42704
DB20000I The SQL command completed successfully.
DB21034E The command was processed as an SQL statement because it was not a
valid Command Line Processor command. During SQL processing it returned:
SQL0204N "STKDRP.T2" is an undefined name. SQLSTATE=42704
DB20000I The SQL command completed successfully.
DB21034E The command was processed as an SQL statement because it was not a
valid Command Line Processor command. During SQL processing it returned:
SQL0204N "STKDRP.T3" is an undefined name. SQLSTATE=42704
DB20000I The SQL command completed successfully.
DB21034E The command was processed as an SQL statement because it was not a
valid Command Line Processor command. During SQL processing it returned:
SQL0204N "STKDRP.T4" is an undefined name. SQLSTATE=42704
DB20000I The SQL command completed successfully.
DB21034E The command was processed as an SQL statement because it was not a
valid Command Line Processor command. During SQL processing it returned:
SQL0204N "STKDRP.T5" is an undefined name. SQLSTATE=42704
DB20000I The SQL command completed successfully.
TABCNT
-----------
6
1 record(s) selected.
TABSCHEMA TABNAME
---------- -----------
STKDRP T0
STKDRP T1
STKDRP T2
STKDRP T3
STKDRP T4
STKDRP T5
6 record(s) selected.
DROP TABLE STKDRP.T0
DB20000I The SQL command completed successfully.
DROP TABLE STKDRP.T1
DB20000I The SQL command completed successfully.
DROP TABLE STKDRP.T2
DB20000I The SQL command completed successfully.
DROP TABLE STKDRP.T3
DB20000I The SQL command completed successfully.
DROP TABLE STKDRP.T4
DB20000I The SQL command completed successfully.
DROP TABLE STKDRP.T5
DB20000I The SQL command completed successfully.
TABCNT
-----------
0
1 record(s) selected.
TABUTHEMA TABNAME
---------- -------
0 record(s) selected.
DB20000I The SQL command completed successfully.
DB20000I The TERMINATE command completed successfully.
Related
When running the following Python code and SQL query on a Teradata Vantage Express server:
#!/usr/bin/env python3
import teradatasql
query = """CREATE VOLATILE TABLE target_table AS (
select * FROM MY_DB.MY_TABLE
)
WITH DATA ON COMMIT PRESERVE ROWS;
SELECT * FROM target_table;"""
con = teradatasql.connect(host="localhost", user="dbc", password="dbc")
cur = con.cursor()
cur.execute(query)
I get the following error:
teradatasql.OperationalError: [Version 17.20.0.7] [Session 2988] [Teradata Database] [Error 3932] Only an ET or null statement is legal after a DDL Statement.
However, when using bteq (Teradata's CLIv2 db connector), and running the same query it works like a charm and doesn't throw any error:
BTEQ -- Enter your SQL request or BTEQ command:
CREATE VOLATILE TABLE target_table AS (
select * FROM MY_DB.MY_TABLE
)
WITH DATA ON COMMIT PRESERVE ROWS;
CREATE VOLATILE TABLE target_table AS (
select * FROM MY_DB.MY_TABLE
)
WITH DATA ON COMMIT PRESERVE ROWS;
*** Table has been created.
*** Total elapsed time was 1 second.
BTEQ -- Enter your SQL request or BTEQ command:
SELECT TOP 1 * FROM target_table;
SELECT TOP 1 * FROM target_table;
*** Query completed. One row found. 9 columns returned.
*** Total elapsed time was 1 second.
customer_id customer_token customer_branch customer_num
-------------- ------------------------------ --------------- ------------
8585 452004 83 808038
BTEQ -- Enter your SQL request or BTEQ command:
Any idea?
Note that no useful Google entries were found for either Python based JDBC drivers (e.g. teradatasql) or Node.js based drivers.
In the bteq examples you’ve given there are individual queries being executed; each query is separated by a “;”. However, in the Python code you have combined 2 queries into a single string and are trying to execute that string as a single query - which won’t work.
You need to write the Python code to run each query separately, in the same way that the bteq code does. For example:
query = """CREATE VOLATILE TABLE target_table AS (
select * FROM MY_DB.MY_TABLE
)
WITH DATA ON COMMIT PRESERVE ROWS;”””
con = teradatasql.connect(host="localhost", user="dbc", password="dbc")
cur = con.cursor()
cur.execute(query)
query = “””SELECT * FROM target_table;"""
cur.execute(query)
getting an error on trying to pass a variable as a schema name for an sql file and I need a way to get this done.
I have noticed I do not get any error on passing a variable in a where clause of an sql statement.
I have tried with the below ways:
1)
Shell script 1:
#!/bin/bash
b=`sqlplus -silent $dbconnect #abc.sql prd01`
SQL script:
Set Heading off
Set term off
Spool xyz.csv
Select * from pkk$'&1'_02.tab1
Where
Col = 'S';
ERROR-
ORA-00933: SQL command not properly ended
Shell script 1:
#!/bin/bash
b=`sqlplus -silent $dbconnect #abc.sql prd01`
SQL script:
Set Heading off
Set term off
Spool xyz.csv
Select * from pkk$"&1"_02.tab1
Where
Col = 'S';
ERROR-
ORA-00933: SQL command not properly ended
Shell script 1:
#!/bin/bash
b=`sqlplus -silent $dbconnect #abc.sql prd01`
SQL script:
Set Heading off
Set term off
Spool xyz.csv
Select * from pkk$&1_02.tab1
Where
Col = 'S';
No error:
but waiting prompt to pass a variable
No error on passing the variable in the where clause
Shell script 1:
#!/bin/bash
b=`sqlplus -silent $dbconnect #abc.sql prd01`
SQL script:
Set Heading off
Set term off
Spool xyz.csv
Select * from pkk$prd01_02.tab1
Where
Col = '&1';
No error
In sqlplus, you need to use a '.' if the variable name is followed by something, in your case write your sql like this:
Select * from pkk$&1._02.tab1
Where
Col = 'S';
And, if you tried your script by logging in sqlplus and running it interactively, you would have seen your error.
I am executing below command on Shell bash after connecting to the database
the textfile below has table names in the DB2 database like
TABLE1
TABLE2
..
TABLEN
for tablenam in $(cat textfile)
do
db2 'EXPORT TO $PPL_IXFDRV/PREBKP/tablenam.IXF OF~
IXF MESSAGES /dev/null~
SELECT * FROM $SCHEMA.tablenam'
done
When I run this I get below error
SQL3022N An SQL error "-204" occurred while processing the SELECT string in
the Action String parameter.
I have tried the above command with single quote like below
for tablenam in $(cat textfile)
do
db2 EXPORT TO $PPL_IXFDRV/PREBKP/tablenam.IXF OF~
IXF MESSAGES /dev/null~
SELECT \* FROM $SCHEMA.tablenam
done
This also gives me the same result
What I am trying to do here is unload in IXF format DB2 tables present in the list "textfile" in the Database substituting tablenam in the repeated commands for db2 EXPORT
Try this:
for tablenam in $(cat textfile)
do
db2 "EXPORT TO ${PPL_IXFDRV}/PREBKP/${tablenam}.IXF OF
IXF
SELECT * FROM ${SCHEMA}.${tablenam}"
done
SELECT tab1.column1 FROM DB2.Schema.table1 tab1;
I try to execute this above query from Database 1. The table1 exist in DB2 database. It showing following error.
ORA-00933: SQL command not properly ended
00933. 00000 - "SQL command not properly ended"
No need to mention database name in your select statment. See below:
SELECT tab1.column1 FROM Schema.table1 tab1;
DB Link Usage:
CREATE DATABASE LINK sales.hq.acme.com
CONNECT TO scott IDENTIFIED BY tiger
USING 'sales';
Once this database link is created, you can query tables in the schema SCOTT on the remote database in this manner:
SELECT *
FROM emp#sales.hq.acme.com;
You can also use DML statements to modify data on the remote database:
INSERT INTO accounts#sales.hq.acme.com(acc_no, acc_name, balance)
VALUES (5001, 'BOWER', 2000);
UPDATE accounts#sales.hq.acme.com
SET balance = balance + 500;
DELETE FROM accounts#sales.hq.acme.com
WHERE acc_name = 'BOWER';
You can also access tables owned by other users on the same database. This statement assumes SCOTT has access to ADAM's DEPT table:
SELECT *
FROM adams.dept#sales.hq.acme.com;
The previous statement connects to the user SCOTT on the remote database and then queries ADAM's DEPT table.
Note: Dblinks are used using '#' symbol.
You don't need to prefix the db. Just make sure you are in the right schema using:
ALTER SESSION SET current_schema = schemaname;
I have this batch file that outputs a list of all the tables to a file. I am looking for the command that will input this list and generate a whole list of drop statements to drop all the tables with?
:: droptables.bat
set SQLVER=100
if NOT EXIST "%PROGRAMFILES%\Microsoft SQL Server\100\Tools\BINN\osql.exe" (
#echo MS SQL Server 2008 not found.
set SQLVER=90
if NOT EXIST "%PROGRAMFILES%\Microsoft SQL Server\90\Tools\BINN\osql.exe" (
#echo MS SQL Server 2005 not found.
set SQLVER=80
if NOT EXIST "%PROGRAMFILES%\Microsoft SQL Server\80\Tools\BINN\osql.exe" (
#echo MS SQL Server is not yet installed.
pause
exit
)
)
)
#echo Your SQL Server version is %SQLVER% (100=2008,90=2005, and 80=2000)
if exist "%PROGRAMFILES%\Microsoft SQL Server\%SQLVER%\Tools\BINN\osql.exe" (
"%PROGRAMFILES%\Microsoft SQL Server\%SQLVER%\Tools\BINN\osql" -E
-d "%PROJECT%PD_FSDB_ECitation" -h-1 -Q "select name from sysobjects where
type='U' order by name;" -o tableList.txt
The above query needs to be changed to create a list of drop statements instead of just table names. The tableList.sql file is just a simple list of drop table statements.
After generating the queryList.sql, then I want to run it like so:
osql -E -h-1 -i C:\MyFolder\queryList.txt
I know there is a way to generate a list of SQL statements from a SQL statement but I don't remember how to do it.
Why don't use just use the system stored proc sp_msforeachtable?
Run the following from your osql and you can bypass a lot of the extra work you are doing:
USE <databasename>
exec sp_msforeachtable 'DROP TABLE ?'
This proc basically builds a cursor and executes the query inside the single quotes once for each table, replacing ? with the schema-qualified table name, like dbo.table.
Run the following from your SQL. It is simple and fast to delete tables from your DB:
USE <databasename>
exec sp_msforeachtable 'DROP TABLE ?'
I don't know if there is a command to do it but you can change your select statement so that it creates the drop statement for you:
select '--DROP TABLE ' + name + CHAR(10) + 'DROP TABLE ' + name + ' GO' from sysobjects where type='U'
EDIT: After comment with regards to schema not specified:
SELECT '--DROP TABLE ' + TABLE_NAME + CHAR(10) + 'DROP TABLE ' + QUOTENAME(TABLE_SCHEMA) + '.' + QUOTENAME(TABLE_NAME)
FROM INFORMATION_SCHEMA.TABLES
EDIT: As Remus suggested in the comments, added quotename to make it less vulnerable to sql injection
Here is how I did it:
set SQLVER=100
if NOT EXIST "%PROGRAMFILES%\Microsoft SQL Server\100\Tools\BINN\osql.exe" (
#echo MS SQL Server 2008 not found.
set SQLVER=90
if NOT EXIST "%PROGRAMFILES%\Microsoft SQL Server\90\Tools\BINN\osql.exe" (
#echo MS SQL Server 2005 not found.
set SQLVER=80
if NOT EXIST "%PROGRAMFILES%\Microsoft SQL Server\80\Tools\BINN\osql.exe" (
#echo MS SQL Server is not yet installed.
pause
exit
)
)
)
#echo Your SQL Server version is %SQLVER% (100=2008,90=2005, and 80=2000)
if exist "%PROGRAMFILES%\Microsoft SQL Server\%SQLVER%\Tools\BINN\osql.exe" (
"%PROGRAMFILES%\Microsoft SQL Server\%SQLVER%\Tools\BINN\osql" -E -h-1
-d MYDB -Q "select 'DROP TABLE ' + CAST(name AS
VARCHAR(30)) + ';' from sysobjects where type='U';" -o queries.sql
:: remove sql result count line
type queries.sql | findstr /V rows > queryList.sql
:: rename Identity table in the sql script because it uses a keyword
type queryList.sql | findstr /V /C:"TABLE Identity" > runQueries.sql
echo DROP TABLE [Identity]; >> runQueries.sql
"%PROGRAMFILES%\Microsoft SQL Server\%SQLVER%\Tools\BINN\osql" -E -h-1
-d MYDB -i runQueries.sql -o dropResults1.txt
)
pause
:: Cleanup
del queryList.sql
del dropResults1.txt
del dropResults2.txt
del runQueries.sql
del queries.sql
exit