create or rename dynamic table teradata - teradata

I want to create or rename table with current_date.
For example:
1) create table TABLENAME || CURRENT_DATE
2) rename TABLE_NAME TO TABLE_NAME_||CURRENT_DATE.
How can I do it? Could you give an example?

This will append the current date in YYYYMMDD format to the table name. If YYYYMMDD is already appended to the name it's replaced with the new date.
REPLACE PROCEDURE rename_table_yyyymmdd
(
IN db_name VARCHAR(128) CHARACTER SET Unicode,
IN tbl_name VARCHAR(128) CHARACTER SET Unicode, -- defaults to current database
OUT msg VARCHAR(600) CHARACTER SET Unicode
) SQL SECURITY INVOKER
BEGIN
DECLARE old_name VARCHAR(261) CHARACTER SET Unicode;
DECLARE new_name VARCHAR(261) CHARACTER SET Unicode;
DECLARE sql_stmt VARCHAR(600) CHARACTER SET Unicode;
SET old_name = '"' || Coalesce(db_name,DATABASE) || '"."'
|| Coalesce(tbl_name, '') || '"';
SET new_name = '"' || Coalesce(db_name,DATABASE) || '"."'
-- remove an existing "_YYYYMMDD" at the end of the table name
|| Coalesce(RegExp_Replace(tbl_name, '_[0-9]{8}$'),'')
|| '_' || To_Char(Current_Date, 'yyyymmdd') || '"';
SET sql_stmt = 'RENAME TABLE ' || old_name || ' AS ' || new_name || ';';
EXECUTE IMMEDIATE sql_stmt;
SET msg = 'Table ' || old_name || ' renamed to ' || new_name;
END;
CALL rename_table_yyyymmdd('myDB', 'tablename', msg);
CALL rename_table_yyyymmdd(null, 'tablename', msg);
No error handling, simply fails on errors, e.g. when you run it twice a day or the table doesn't exists or the user has no Drop Table right, etc.

Step 1:
create table dat
(
saledate CURRENT_DATE
)
Step 2:
CREATE TABLE database.new_table AS
database.dat WITH DATA;
You can use sysdate or getdate to get current date.

Related

Rename column if it has single quote

I need to rename column in my oracle database using pl/sql. For example you have table like this.
CREATE TABLE TEST(
id int,
"'test1" varchar(80),
"test2" varchar(80)
);
and you need to remove all quotes from it. I wrote anonymous block and there is the problem:
...
FOR column_rec IN (SELECT column_name FROM USER_TAB_COLUMNS WHERE TABLE_NAME=table_rec.TABLE_NAME) LOOP
new_column_name := column_rec.COLUMN_NAME;
new_column_name := REPLACE(new_column_name, chr(34), '');
new_column_name := REPLACE(new_column_name, chr(39), '');
...
EXECUTE IMMEDIATE
'ALTER TABLE '
|| table_rec.TABLE_NAME
|| ' RENAME COLUMN '
|| column_rec.COLUMN_NAME
|| ' TO '
|| new_column_name;
...
But if column_rec.COLUMN_NAME has just a single quote in it, this script will fail with exception ORA-01756, which means there is no closing quote. How can I avoid this exception?
Just use double quotes to wrap the columns' names even in your script; for example, this works:
alter table test rename column "'test1" to test1
Your script could be edited as:
EXECUTE IMMEDIATE
'ALTER TABLE '
|| table_rec.TABLE_NAME
|| ' RENAME COLUMN "' /* open the quote */
|| column_rec.COLUMN_NAME
|| '" TO ' /* and close */
|| new_column_name;
Also, notice that in this way all the renamed columns will be upper case; if this is what you need, well done, otherwise you have to wrap with double quotes even the new names:
...
|| '" TO "' /* and close, and reopen */
|| new_column_name || '"'; /* and close again */

How to delete duplicate rows from all of my oracle database tables, using PL/SQL?

A generic way to remove perfectly duplicated rows from all tables owned by a certain user.
Here's the stored procedure for it. Don't forget to replace 'YOUR_USERNAME_HERE' with your username.
CREATE OR REPLACE PROCEDURE DELETE_DUPLICATES_FROM_DB
IS
TABLE_COLUMNS VARCHAR2(10000);
DELETE_STATEMENT VARCHAR2(10000);
CURSOR ALL_MY_TABLES IS SELECT TABLE_NAME FROM ALL_TABLES WHERE OWNER = 'YOUR_USERNAME_HERE';
BEGIN
FOR MY_TABLE IN ALL_MY_TABLES
LOOP
SELECT LISTAGG(COLUMN_NAME, ',') WITHIN GROUP (ORDER BY 1) INTO TABLE_COLUMNS FROM USER_TAB_COLUMNS WHERE TABLE_NAME = MY_TABLE.TABLE_NAME;
DELETE_STATEMENT := 'DELETE FROM ' || MY_TABLE.TABLE_NAME || ' WHERE ROWID NOT IN (SELECT MIN(ROWID) FROM ' || MY_TABLE.TABLE_NAME || ' GROUP BY ' || TABLE_COLUMNS || ');';
EXECUTE IMMEDIATE DELETE_STATEMENT;
DBMS_OUTPUT.PUT_LINE(DELETE_STATEMENT);--print the statements we run
END LOOP;
END;

PLSQL - Cursor cannot be used in dynamic sql

I have a dynamic SQL query which is constructed in a string.
The procedure should return a 'REF CURSOR'.
I get the error PLS-00455 when I try to open the cursor for the query.
Cursor definition
CURSOR cu_SiteList IS
SELECT SEC_NN.SRV_ID
,SEC_NN.SRV_NAME
,SEC_NN.SRV_COMTYP_CODE
FROM SEC_NN
,COM_SITE_STATE_T
WHERE SEC_NN.SRV_COMTYP_CODE <> 1
AND SEC_NN.SRV_ID = 2;
TYPE SITE_LIST_TYP IS REF CURSOR RETURN cu_SiteList%ROWTYPE;
Here is the query:
p_SiteList SITE_LIST_TYP;
lv_QueryStr := ' SELECT SEC_NN.SRV_ID ' ||
' ,SEC_NN.SRV_NAME ' ||
' ,SEC_NN.SRV_COMTYP_CODE ' ||
' FROM SEC_NN_, ' ||
' COM_SITE_STATE_T ' ||
' WHERE SEC_NN.SRV_COMTYP_CODE <> 1 ' ||
' AND SEC_NN.SRV_MODE_CODE = 2' ||
' AND SEC_NN.SRV_ID = COM_SITE_STATE_T.SRV_ID';
OPEN p_SiteList FOR lv_QueryStr;
As you can see I only use 3 columns from SEC_NN table, so creating a cursor that is a ROWTYPE of the entire table will not work for me.
How can overcome this?
Thanks in advance.
From the comments, the fix is to declare the cursor as a 'weak' ref cursor, by replacing the line
p_SiteList SITE_LIST_TYP;
with
p_SiteList SYS_REFCURSOR;

Aliasing in Bulk Collect giving error of unimplemented feature

The problem statement: The user would specify a name based on which I have to pull names of two tables from a table and then extract values from those tables.I have created a pl/sql procedure for that and since the select query can return n number of rows I'm using Bulk Collect. I have created and object based on the fields I want to extract. Now the problem is that the columns are common in both the tables, so if I don't use alias I get ambiguous column error and if I use that I get the error of unimplemented feature.
here's my code:
create or replace type recon_obj_vib
is object (RECON_TABLE_KEY NUMBER(19)
,RECON_CHGLOGATTR_IDXLST VARCHAR2(1000 CHAR));
create or replace type recon_tab_vib
is table of recon_obj_vib;
create or replace PROCEDURE noMatchReport_proc(tableDesc IN VARCHAR2)
IS
l_recon_tab_vib recon_tab_vib := recon_tab_vib();
n Integer :=0;
out varchar2(2000);
tableName1 varchar2(25);
tableName2 varchar2(25);
tableDesc_without_space varchar2(25);
tableDesc_ra varchar2(25);
BEGIN
tableDesc_without_space:=Regexp_Replace(tableDesc,'\s');
tableDesc_ra:=UPPER('RA_' || tableDesc_without_space || ' %');
out:= 'Select recon_table_name from recon_tables where recon_table_desc = (:value) and rownum=1 and RECON_TABLE_name like (:userName)';
execute immediate out into tableName1 USING tableDesc,tableDesc_ra;
out:= 'Select recon_table_name from recon_tables where recon_table_desc = (:value) and rownum=1 and RECON_TABLE_name not like (:userName)';
execute immediate out into tableName2 USING tableDesc,tableDesc_ra;
out:='Select a.RECON_TABLE_KEY,a.RECON_CHGLOGATTR_IDXLST BULK COLLECT INTO l_recon_tab_vib from ' || tableName1 || ' a , ' || tableName2 || ' b where a.RE_KEY = b.RE_KEY and rownum=1';
execute immediate out into l_recon_tab_vib;
FOR i IN 1..l_recon_tab_vib.COUNT
LOOP
DBMS_OUTPUT.PUT_LINE('RECON_TABLE_KEY '|| l_recon_tab_vib(i).RECON_TABLE_KEY ||' RECON_CHGLOGATTR_IDXLST ' || l_recon_tab_vib(i).RECON_CHGLOGATTR_IDXLST );
END LOOP;
END;
This part:
out:='Select a.RECON_TABLE_KEY,a.RECON_CHGLOGATTR_IDXLST BULK COLLECT INTO l_recon_tab_vib from ' || tableName1 || ' a , ' || tableName2 || ' b where a.RE_KEY = b.RE_KEY and rownum=1';
execute immediate out into l_recon_tab_vib;
Should be:
out:='Select a.RECON_TABLE_KEY,a.RECON_CHGLOGATTR_IDXLST from '
|| tableName1 || ' a , ' || tableName2
|| ' b where a.RE_KEY = b.RE_KEY and rownum=1';
execute immediate bulk collect into l_recon_tab_vib;
i.e. the BULK COLLECT INTO clause is part of the calling PL/SQL not part of the dynamic SQL.

Trigger is not working properly?

Hello I exported database using datapump another schema so this synonyms must be in another new schema.
My old one is KTECH and new one is LTECH
DECLARE
strSynonyms_KTECH VARCHAR2(3000) := 'KTECH ';
strSynonyms_LTECH VARCHAR2(3000) := 'LTECH';
strCommand VARCHAR2(33865);
BEGIN
LOOP
FOR Synonym IN (SELECT * FROM ALL_SYNONYMS WHERE OWNER = strSynonyms_KTECH)
strCommand := 'CREATE OR REPLACE SYNONYM ' ||
Synonym.KTECH || '.' || Synonym.SYNONYM_NAME ||
' FOR ' || strSynonyms_LTECH || '.' ||
Synonym.TABLE_NAME;
EXECUTE IMMEDIATE strCommand;
END LOOP;
END;
I tried to run it but it shows me error.
you can export database synonyms from old schema as text file by using pl/sql or TOAD, then save the exported file as script, edit it then execute it on new schema.
by plsql developer:
by Toad:

Resources