SQLite drop table when row in another table is deleted - sql

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.

Related

Create a table in dbshell with django

here is my code :
frontgreat=> CREATE TABLE contact_titlemessagesuggestion;
ERROR: syntax error at or near ";"
LINE 1: CREATE TABLE contact_titlemessagesuggestion;
i don't understand why it's not working and why it's an syntax error.
frontgreat=> DROP TABLE contact_titlemessagesuggestion;
ERROR: table "contact_titlemessagesuggestion" does not exist
have no syntax error and work fine.
Regards
You can normally not create a table without any columns. Therefore one often either has to list the columns, or use for example a query that provides both data (but meta-data as well) to construct the columns in the table.
For example:
CREATE TABLE contact_titlemessagesuggestion (
pk INT
);

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.

Stored Procedure refuses to delete column that it creates

I've created a Stored Procedure that refreshes the data in a table. It first re-loads the entire table. Next, several filters are applied. (Example: the column 'Model' must equal 'W'; all rows with model 'B' are deleted.) This happens after the table has been loaded (and not during) because I want to log how many rows are deleted because of each individual filter. After the filters have been applied, some columns contain the same value in every row (the other values were deleted in the filtering process). These columns are now useless, so I want to delete them.
This seems to be problematic for SQL Server. When given the command to execute the SP, it indicates that the columns it is supposed to remove in its final step do not currently exist and refuses to run. That is technically correct, the columns currently don't exist, but they will be created by the SP itself.
Some mockup code:
CREATE PROCEDURE dbo.Procedure AS (
DROP TABLE dbo.Table
SELECT * INTO dbo.Table FROM dbo.View
INSERT INTO dbo.Log VALUES (GETDATE(),(SELECT COUNT(1) FROM dbo.Table))
DELETE FROM dbo.Table WHERE Model <> 'W'
INSERT INTO dbo.Log VALUES (GETDATE(),(SELECT COUNT(1) FROM dbo.Table))
ALTER TABLE dbo.Table DROP COLUMN Model
)
Error code when executing:
[2016-09-02 12:25:20] [S0001][207] Invalid column name 'Model'.
How do I circumvent this problem and get the SP to run?
If I understand correctly, you can use dynamic SQL:
exec sp_executesql 'ALTER TABLE dbo.Table DROP COLUMN Model';
Syntax to remove any column from table in SQL Server is
ALTER TABLE TableName DROP COLUMN ColumnName ;
This may be cause for issue.
Can you check one more time for the existency of the column 'Model' exists in the view.
because i have tried with the same scenario and its works for me..

ON CONFLICT DO UPDATE has missing FROM-clause

I have a simple table (id and name column, both unique), which I am importing a tab delimited CSV file.
I am running psql 9.5, and wanted to try out the new ON CONFLICT feature to update the name column if the ID already exists.
CREATE TEMP TABLE tmp_x AS SELECT * FROM repos LIMIT 0;
COPY tmp_x FROM '/Users/George/git-parser/repo_file' (format csv, delimiter E'\t');
INSERT INTO repos SELECT * FROM tmp_x
ON CONFLICT(name) DO UPDATE SET name = tmp_x.name;
DROP TABLE tmp_x;
I am getting this error:
SELECT 0
COPY 1
ERROR: missing FROM-clause entry for table "tmp_x"
LINE 4: ON CONFLICT(name) DO UPDATE SET name = tmp_x.name;
^
Query failed
PostgreSQL said: missing FROM-clause entry for table "tmp_x"
Not too sure whats going wrong here.
If you look at the documentation of the ON CONFLICT clause, it says this about the "conflict action":
The SET and WHERE clauses in ON CONFLICT DO UPDATE have access to the existing row using the table's name (or an alias)
In your query, the target table is repos.
tmp_x, on the other hand, is the source of the data you are trying to insert, but the ON CONFLICT clause cannot "see" that - it is looking at a particular row that has been calculated and failed. Consider if you'd written something like this:
INSERT INTO repos SELECT max(foo_id) FROM tmp_x
Clearly, it wouldn't make sense for a row which failed to insert into repos to have access to any one row from tmp_x.
If there was no way of seeing the rejected data, the whole feature would be pretty useless, but if we read on:
... and to rows proposed for insertion using the special excluded table.
So instead, you need to access the magic table alias excluded, which contains the values which you tried to insert but got a conflict on, giving you this:
INSERT INTO repos SELECT * FROM tmp_x
ON CONFLICT(name) DO UPDATE SET name = excluded.name;
If it seems weird that an imaginary table name pops up for this purpose, consider that a similar thing happens when writing triggers, where you get OLD and NEW (depending on the kind of trigger you're writing).

Oracle - Zombie Table

I'm having this odd problem since yesterday. I've tried several options and I actually reinstalled ORACLE and the DB itself.
Here's the problem: I have this table that is somekind of zombie. Here are the symptoms:
SELECT TABLE_NAME FROM USER_TABLES WHERE TABLE_NAME='MYTABLE'
Returns a record, meaning that the table exists.
SELECT COLUMN_NAME FROM USER_TAB_COLUMNS WHERE TABLE_NAME = 'MYTABLE'
Returns all the columns of MYTABLE. So far so good, the table exists.
SELECT * FROM MYTABLE
Returns ORA-00942: table or view does not exist.
At this point I'm quite confused: the table seems to exist on the USERTABLES but I cannot SELECT over it?
CREATE TABLE MYTABLE (Foo NUMBER) TABLESPACE MYTABLESPACE
Returns:
ORA-00604: error occurred at recursive SQL level 1
ORA-00001: unique constraint (SYS.I_OBJ2) violated
I do not understand this error. But the best is yet to come.
SELECT * FROM MYTABLE
Surprisingly, the above query (an exact copy of the 3rd query) returns several records now!
Moreover, I noticed that the column Foo is not present: the table I now see is my initial table that had other columns.
DROP TABLE MYTABLE
I now try to drop the table and I get the following errors:
ORA-00604: error occurred at recursive SQL level 1
ORA-00942: table or view does not exist
ORA-06512: at line 19
SELECT * FROM MYTABLE
More confused than ever, I try the above query and, surprise surprise, the table no longer exists.
I don't undestand this: the table is on USERTABLES but I cannot SELECT over it, however, if I create a new table with the same name, I get an error but now I can SELECT over the previous version of that table with several records.
Any thoughts ? I really need your help :(
EDIT - I checked now: I'm unable to drop ANY table. This might just be a new symptom.
Solution
The problem was that MDSYS.SDO_GEOR_SYSDATA_TABLE table was missing and a drop event trigger was trying to access it, generating the error. The solution was restoring that table.
If have privileges, try this query:
SELECT *
FROM dba_objects
WHERE object_name = 'MYTABLE';
And see what objects exist with that name. It might point you in the right direction.
You didn't qualify the schema names when trying to select and drop. The CURRENT_SCHEMA of your session may be different form the log-on user. Check by trying
select SYS_CONTEXT('USERENV', 'CURRENT_SCHEMA') from dual;
Instead of describing what the output was, could you please copy/paste the complete output for us?
Lastly, can you exclude that someone messed up the dictionary? You know, SYSDBA can do anything....