Move data from one table to another with Redshift - sql

I wanted to move log datas that have a specific user_id to a new table on Redshift. I've started playing with WITH block like :
WITH moved_rows AS (
DELETE FROM sensor_log_enable
USING sensor_log_disable
WHERE sensor_log_enable.user_id
IN (16,17,18)
RETURNING sensor_log_enable.*
)
INSERT INTO sensor_log_disable
SELECT * FROM moved_rows;
But redshift doesn't like it.
ERROR: syntax error at or near "DELETE"
LINE 2: DELETE FROM active_connections
Redshift doesn't seem to include DELETE in WITH block. What's the best strategy then ?
1 INSERT INTO then an INNER JOIN OR LEFT OUTER JOIN with DELETE?

To 'move' data between tables, you must:
Use INSERT INTO to copy the data to the target table
Use DELETE to delete the data from the source table
They must be performed as separate SQL commands. You can, however, wrap those commands in BEGIN/END statements to commit them as one transaction:
BEGIN;
INSERT INTO...;
DELETE FROM...;
END;

Related

Why use MERGE statements that only do 1 operation in SQL?

In our code base I see a lot of SQL MERGE statements that only perform an UPDATE or only perform an INSERT or only perform a DELETE. I am having a hard time understanding why developers don't just write an insert or an update or a delete command.
What are the pros and cons of using merge statements that only execute one command?
From what I understand, merges are more problematic, if say a table's hash distribution column changes, or if a row gets updated more than once it will throw an exception (maybe a logic problem at that point, but will throw an exception nonetheless).
Example:
MERGE INTO dbo.my_dltd_recs AS dst
USING (SELECT *
FROM dbo.my_recs
WHERE dltd_ind = 'Y') src
ON (dst.my_skey = src.my_skey)
WHEN NOT MATCHED
-- only operation is INSERT, WHY USE MERGE
THEN INSERT (my_skey,
colA,
colB)
VALUES
( src.my_skey,
src.colA,
src.colB);

Creating a SQL view that will accept inserted values

I have created a SQL view that retrieves the result set I desire but when I try to add a new set of values it fails. When searching around on the net it appears that VIEW has a few limitations and some types of joins may not be allowed, I have tried to create the view a few different ways but with no success yet, would anyone happen to know a way I could rewrite this create view query that would allow me to insert new values into it?
The view:
CREATE VIEW NATIONAL_ITEMS
AS
SELECT item.itemno, item.itemdesc, item.itemprice
FROM item
FULL OUTER JOIN invoiceitem ON item.itemno = invoiceitem.itemno
WHERE item.itemdesc LIKE '%National%'
AND invoiceitem.invoiceno IS NULL
WITH CHECK OPTION;
My insert statement that does not work:
INSERT INTO NATIONAL_ITEMS
VALUES ('123-456', 'National TV', 100);
I get this error:
Error starting at line : 1 in command -
INSERT INTO NATIONAL_ITEMS VALUES ('123-456', 'National TV', 100)
Error at Command Line : 1 Column : 1
Error report -
SQL Error: ORA-01733: virtual column not allowed here
01733. 00000 - "virtual column not allowed here"
Any help would be greatly appreciated, thank you.
You have two options for the view in order to insert in the view.
First, Your View must contain all the keys present in the table on which you are creating the view i.e there must be no DISTINCT OR GROUP BY clause.
If you performing JOIN on the tables same is applicable for all join tables, all keys from the table must be present in the view and there must be no DISTINCT OR GROUP BY clause.
The table which has 1:1 row relationship with the rows in the view called Key preserving table
Second, you can create instead of trigger on the view. The trigger will be fired instead of INSERT, UPDATE, OR DELETE and in the trigger, you can handle the DML statement.
Since your table is not key preserving then you can make use of INSTEAD OF TRIGGER.
CREATE OR REPLACE TRIGGER NATIONAL_ITEMS_TRG
INSTEAD OF INSERT
ON NATIONAL_ITEMS
FOR EACH ROW
BEGIN
INSERT INTO ITEM(itemno, itemdesc, itemprice) VALUES (:NEW.itemno, :NEW.itemdesc, :NEW.itemprice);
END;

DB2 SQL statement - is it possible to A) declare a temporary table B) populate it with data then C) run a select statement against it?

I have read only access to a DB2 database and i want to create an "in flight/on the fly" or temporary table which only exists within the SQL, then populate it with values, then compare the results against an existing table.
So far I am trying to validate the premise and have the following query compiling but failing to pick anything up with the select statement.
Can anyone assist me with what I am doing wrong or advise on what I am attempting to do is possible? (Or perhaps a better way of doing things)
Thanks
Justin
--Create a table that only exists within the query
DECLARE GLOBAL TEMPORARY TABLE SESSION.TEMPEVENT (EVENT_TYPE INTEGER);
--Insert a value into the temporary table
INSERT INTO SESSION.TEMPEVENT (EVENT_TYPE) VALUES ('1');
--Select all values from the temporary table
SELECT * FROM SESSION.TEMPEVENT;
--Drop the table so the query can be run again
DROP TABLE SESSION.TEMPEVENT;
If you look at the syntax diagram of the DECLARE GLOBAL TEMPORARY TABLE statement, you may note the following block:
.-ON COMMIT DELETE ROWS---.
--●--+-------------------------+--●----------------------------
'-ON COMMIT PRESERVE ROWS-'
This means that ON COMMIT DELETE ROWS is default behavior. If you issue your statements with the autocommit mode turned on, the commit statement issued automatically after each statement implicitly, which deletes all the rows in your DGTT.
If you want DB2 not to delete rows in DGTT upon commit, you have to explicitly specify the ON COMMIT PRESERVE ROWS clause in the DGTT declaration.

SQLite drop table when row in another table is deleted

I've been wrestling with setting up a trigger and keep getting the error:
SQL logic error near "DROP": syntax error
I have several tables main_table, other_one, other_two, etc.
main_table has several columns with the primary key column named filehash
The values in the primary key column of main_table are also the names of the other_* tables
So, if I delete a row in main_table with a primary key of other_one, I want the trigger to DROP the table other_one too
Here's the trigger statement that is producing the error
CREATE TRIGGER remove_other_one AFTER DELETE ON 'main_table'
WHEN (OLD.filehash == 'other_one')
BEGIN
DROP TABLE IF EXISTS 'other_one' ;
END remove_other_one;
EDIT: the 'fuller' error I get when I run the trigger statement in SQLite DB Browser is:
near "DROP": syntax error: CREATE TRIGGER remove_other_one AFTER DELETE ON 'main_table' WHEN (OLD.filehash == 'other_one') BEGIN DROP
Based on SQLite trigger doc I believe that it is not possible:
There is no option for DDL/dynamic SQL inside trigger.
I guess that you wanted to achieve something like PostgreSQL DBFiddle Demo 1 and Demo 2
You could handle your case in application code. Anyway table per date/customer/hash almost always indicates poor design and in long run will cause more problems.

Using SQl Server CE; Possible to Insert Only If Not Exists and Delete if Exists?

I have a One Field Table in SQL CE which I need a SQL Statement for. The objective is to Delete the record if it already exists and insert the record if it does not exist. Is the possible with SQL CE?
INSERT INTO Source_Table
SELECT 'myvalue' AS Expr1
WHERE (NOT EXISTS
(SELECT Source_Data
FROM Source_Table AS Source_Table_1
WHERE (Source_Data = 'myvalue')))
Why not just...
DELETE Source_Table WHERE Source_Data = 'myvalue'
GO
INSERT INTO Source_Table (Source_Data) values('myvalue')
I'm not sure what the point of deleting a record and then inserting the same data would be, but this should accomplish it.
If the aim is to literally delete if it exists and only insert it if it does not exist, then you need to do what you've written.
If the aim is to insert if it doesn't exist and replace if it does, Adam's correct that you may as well just always run the delete followed by the insert. I'd run both in the same statement batch, to save overhead.
Were there more than one field, of course you'd do an update, not a delete followed by insert. (But delete followed by insert is how Sybase internally performs updates.)