snowflake: create or replace table when only a condition is met - sql

I have a requirement to create or replace a table only if certain variable value is 1
SET variable = (select statement) -- $variable will be 1 or 0 depending on value returned from select statment
create or replace table2 as select * from table1 (only if $variable =1)
Is there any way to do it? If the variable value is 0, the create statement should be skipped

Using Snowflake Scripting block:
-- CREATE TABLE table1 AS SELECT 1 AS col;
SET variable = (SELECT 1);
BEGIN
IF ($variable = 1) THEN
create or replace table table2 as select * from table1;
END IF;
END;
Variable could be defined also at Snowflake Scripting block level:
DECLARE
variable INTEGER := (SELECT 1);
BEGIN
IF (:variable = 1) THEN
create or replace table table2 as select * from table1;
END IF;
END;

Related

Trigger code not working in oracle to avoid duplicate data

Below trigger code(converted from MSSQL) in oracle is not working.
The two columns should not have duplicate row in the table. I'm creating a trigger for accomplishing this.
Can anyone help in updating/correcting the above code to be used in my trigger?
/*
**Unique Constraint for TestOracle - TestTinyInt.
*/
if (Update(UpdOperation) or Update(TestTinyInt)) THEN
IF Exists(
SELECT * FROM inserted i INNER LOOP JOIN TestOracle x ON
(i.TestTinyInt=x.TestTinyInt)
WHERE i.updoperation IN (0, 1) AND x.updoperation IN (0, 1) GROUP BY x.TestTinyInt
HAVING COUNT(*) > 1)
BEGIN
RAISERROR( 'Invalid attempt to enter duplicate TestTinyInt in TestOracle', 16, -1 )
ROLLBACK TRAN
RETURN
END
END
The best way is to create 2 unique index on each of columns. By doing this you are eliminating duplication in particual column(like #a_horse_with_no_name mentioned).
For other case you don't need to use triger, you need only simple where condition
where Column_A not in (select Column_B from table) and Column_B not in (Select Column_A in table).
EDIT:
It if have to be done in trigger THEN :
create or replace trigger ... instead of insert or update on ...
Declare
dummy number;
Begin
select 1 into dummy from dual where :new.Column_A in (select Column_B from table) or new:.Column_B in (Select Column_A in table);
if dummy <> 1 THEN
INSERT
END IF;
END;
EDIT2: IF you don't want unique index and tirgger here is solution :
create or replace trigger ... instead of insert or update on ...
Declare
dummy number;
Begin
select count(*) into dummy from(
SELECT COL1 FROM (
(select :new.Column_A col1 from dual
UNION
select :new.Column_B from dual))
INTERSECT
SELECT COL2 FROM (
( SELECT COLUMN_A COL2 from table
UNION
SELECT COLUMN_B from table));
if dummy = 0 THEN
INSERT
END IF;
END;

Same value being inserted into table with cursor

I'm trying to dynamically count the number of null values held in a table. So far I have this:
BEGIN
DECLARE STMT VARCHAR(2000);
FOR v AS CRS CURSOR FOR
SELECT NAME
FROM SESSION.TT1
DO
SET STMT = 'UPDATE SESSION.TT1 TT1
SET NULL_COUNT = (
SELECT COUNT(*) - COUNT('''||v.NAME||''') NULL_COUNT
FROM Table1
)
WHERE TT1.COLUMN_NAME = '''||v.NAME||'''';
EXECUTE IMMEDIATE STMT;
END FOR;
END
This runs fine, and does populate the temp table with data, but it updates every row with the same value (which is obviously incorrect).
Where have I gone wrong?
Note:
The temporary table, TT1, was generated by another procedure, it contains two columns; NAME, and NULL_COUNT. All values in the NULL_COUNT column are undefined at this point, and the NAME column contains column names retrieved from syscolumns.
I also tried removing the row and then inserting a new row rather than updating on the matched column name but this provides the same results.
You need double quotes (or no quotes) around the column name, otherwise you are are simply counting a literal value, rather than the column...
DROP TABLE TABLE1#
CREATE TABLE TABLE1(C INT)#
INSERT INTO TABLE1 VALUES(NULL),( NULL)#
DECLARE GLOBAL TEMPORARY TABLE TT1(NAME VARCHAR(128), NULL_COUNT BIGINT)#
INSERT INTO SESSION.TT1 VALUES ('C',null)#
BEGIN
DECLARE STMT VARCHAR(2000);
FOR v AS CRS CURSOR FOR
SELECT NAME
FROM SESSION.TT1
DO
SET STMT = 'UPDATE SESSION.TT1 TT1
SET NULL_COUNT = (
SELECT COUNT(*) - COUNT("'||v.NAME||'") NULL_COUNT
FROM TABLE1
)
WHERE TT1.NAME = '''||v.NAME||'''';
EXECUTE IMMEDIATE STMT;
END FOR;
END
#
SELECT * FROM SESSION.TT1
#
NAME NULL_COUNT
---- ----------
C 2

Insert Mulitple rows in a OUT parameter in a User-defined Table type HANA

I am stuck at a place.
There is a procedure that checks for something and inserts into an table type upon successful determination of that condition.
But i can insert only once in the table type. Is there a way to insert again and again into the table type.
PROCEDURE "hello"."helloWorld.db::sampleException" (OUT TRACE_RECORD "hello"."LogTrace" )
LANGUAGE SQLSCRIPT AS
BEGIN
DECLARE i int;
select count(*) into i from "hello"."REGION";
IF :i > 1 then
TRACE_RECORD = SELECT '1' AS "LogID", '1' AS "TraceID" FROM DUMMY;
end if;
IF :i > 2 then
TRACE_RECORD = SELECT '2' AS "LogID", '2' AS "TraceID" FROM DUMMY;
end if;
END;
What i get on executing the procedure is only the last record "2,2".
How can i insert both the records 1,1 and 2,2.
Note: I do not want to use Temporary Tables.
Any help on this..
Thanks.!
Editing the Question a bit:
-I have to use Table TYPE (till the time there is no optimal way better than it)
-I have to insert more than 20-30 records in the table type.
Do you have to write this as a procedure? A table-valued function seems more suitable:
CREATE FUNCTION f_tables4 (in_id INTEGER)
RETURNS TABLE (
"LogID" VARCHAR(400),
"TraceID" VARCHAR(400)
)
LANGUAGE SQLSCRIPT
AS
BEGIN
RETURN
SELECT t."LogID", t."TraceID"
FROM (
SELECT 1 AS i, '1' AS "LogID", '1' AS "TraceID" FROM DUMMY
UNION ALL
SELECT 2 AS i, '2' AS "LogID", '2' AS "TraceID" FROM DUMMY
) t
JOIN (SELECT count(*) AS cnt FROM "hello"."REGION") c
ON c.cnt > t.i
END

Oracle trigger with select inside that returns multiple results

I have the trigger
CREATE OR REPLACE TRIGGER my_trigger
AFTERE DELETE OR INSERT OR UPDATE ON my_table
FOR EACH ROW
DECLARE
V_PROJECT_ID VARCHAR2(10);
BEGIN
SELECT PJ_ID INTO V_PROJECT_ID FROM PROJECT_ROLES_GROUPS
WHERE GRP_ID = :OLD.GRP_ID;
UPDATE PROJECTS SET TOCUHED = 1 WHERE ID = V_PROJECT_ID;
END;
but the select statement inside the trigger returns multiple values.
How should I handle this case?
How about using in for the query instead of a variable?
BEGIN
UPDATE PROJECTS
SET TOUCHED = 1
WHERE ID IN (SELECT PJ_ID
FROM PROJECT_ROLES_GROUPS
WHERE GRP_ID = :NEW.GRP_ID
);
END

MySQL Backup Table if it Exists

I am trying to write a script that will copy all the data in table a to table b if table a exists. Table b is the exact same structure as table a would be if it exists, though it may not. I am able to copy using the following statement: INSERT INTO 'B' SELECT * FROM 'A', but I don't know where to use IF EXISTS, or if I even can to determine if I an perform the insertion. I am trying to do this in SQL only as it will be run through as a .sql script from the command line.
MySQL only:
DROP PROCEDURE IF EXISTS myupdate;
DELIMITER //
CREATE PROCEDURE myupdate ()
BEGIN
DECLARE found VARCHAR(64);
SET found = (SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = Database() AND TABLE_NAME = 'A');
IF found = 'types' THEN
INSERT INTO B SELECT * FROM A;
SELECT 'A into B';
ELSE
SELECT 'A not found';
END IF;
END;//
DELIMITER ;
CALL myupdate();
DROP PROCEDURE myupdate;
Expand to you're liking comparing the column definition in INFORMATION_SCHEMA.COLUMNS for A & B if you need finer control.
I have accepted Wrikken's answer but am using this as my final code. I need to reuse the procedure he provided for multiple tables, so I modified it slightly. It makes the assumption that the backup table has already been created.
DROP PROCEDURE IF EXISTS tableUpdate;
DELIMITER //
CREATE PROCEDURE tableUpdate(name VARCHAR(32))
BEGIN
DECLARE cnt tinyint(1);
DECLARE btable VARCHAR(36);
SET btable = CONCAT(name,'BAK');
SET cnt = (SELECT COUNT(TABLE_NAME) FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = 'TAA' AND TABLE_NAME = name);
IF cnt > 0 THEN
SET #q:= CONCAT('INSERT INTO ',CONCAT(btable,CONCAT(' SELECT * FROM ',name)));
PREPARE stmt FROM #q;
EXECUTE stmt;
COMMIT;
ELSE
SELECT 'No update necessary.';
END IF;
END;//
DELIMITER ;
CALL tableUpdate('A');
DROP PROCEDURE tableUpdate;
You can do so by performing the following:
select count(*) from my_tables where table_name='b';
If count>0 then
update b...;
else
create table b;
insert into my_tables(table_name) values('b');
insert into b...;
end if;