Can I insert into different databases depending on a query in SQLite? - sql

I have two SQLite databases attached into one connection: db1 and db2. I have a view that UNIONS the tables from both databases and adds a column 'database' specifying which database it came from. I am trying to create a trigger on insert into the view that will instead insert into the correct database.
Imagine the following schema for table Data:
id INTEGER PRIMARY KEY,
parent INTEGER,
data TEXT
This would be the schema for the view DataView:
id INTEGER PRIMARY KEY,
database TEXT,
parent INTEGER,
data TEXT
What I have so far:
CREATE TRIGGER DataViewInsertTrigger AFTER INSERT ON DataView
BEGIN
INSERT INTO database.Data
SELECT database
FROM DataView
WHERE id=new.parent
END;
Is what I'm trying to do even possible? If so, how would I finish the trigger?

No, you cannot insert into an entirely different database based on information you get in a trigger. The trigger executes with a context that is specific to the database which invoked it. The other database would be in a completely unrelated file, in SQLite.
The fact that you have a single connection attaching the two doesn't make one available from the other. What would happen if you tripped the trigger from a query made via a connection which only loaded the one DB?
Perhaps you want two tables in the same database?

While Borealid is correct that the trigger itself cannot insert into a different file, what you can do is call a custom sqlite function which itself generates a query to insert into a different file.

Related

Transfer data to a newly created view from a table in another database in ssms

I have two different databases. Let's say 'DbOne' and 'DbTwo'.
Is there any way to do the followings?
Create a view in DbOne
Transfer data in a particular table from DbTwo to the newly created view in DbOne.
I am using SSMS and still figuring out the appropriate query..
Please give me any advice.
You need INSERT / SELECT statement - eg.
INSERT INTO DbOne..NewView
SELECT * FROM DbTwo..SourceTable
However, depending on the structure of both tables, you may need to specify the particular columns in the SELECT statement, to match the structure of the target table. (By the way, note that data is always going into a TABLE - not a VIEW. You can do an INSERT into a VIEW, but only under certain conditions)

How to encrypt/decrypt data in some columns of a table and when a new record gets inserted it should also get encrypt

i know like this to insert a new record
INSERT INTO dbo.Customer_data (Customer_id, Customer_Name, Credit_card_number)
VALUES (25665, 'mssqltips4', EncryptByKey( Key_GUID('SymmetricKey1'), CONVERT(varchar,'4545-58478-1245') ) );
but i want to insert a new record with a normal insert statement which should get encrypted.
ex:
INSERT INTO dbo.Customer_data (Customer_id, Customer_Name, Credit_card_number)
VALUES (25665, 'mssqltips4','4545-58478-1245') ) );
Few months ago I had similar situation. A table containing personal data need to have some of the columns encrypted, but the table is used in legacy application and have many references.
So, I you can create a separate table to hold the encrypted data:
CREATE TABLE [dbo].[Customer_data_encrypted]
(
[customer_id] PRIMARY KEY -- you can create foreign key to the original one, too
,[name] VARBANRY(..)
,[cretit_card_numbe] VARBINARY(..)
);
Then create a INSTEAD OF INSERT UPDATE DELETE trigger on the original table.The logic in the trigger is simple:
on delete, delete from both tables
on update/insert - encrypt the data and insert in the new table; use some kind of mask to the original table (for example *** or 43-****-****-****)
Then, perform a initial migration to move the data from the original table to the new one and then mask it.
Performing the steps above are nice because:
every insert/update to the original table continue to works
you can create the trigger with EXECUTE AS OWNER in order to have access to the symmetric keys and perform changes directly in the T-SQL statement without opening the certificates or by users who have not access to them
in all reads references you are going to get mask data, so you are not worried for breaking the application critically
having trigger gives you ability to easy create and changes information
It depends on your environment and business needs because for one of the tables I have stored the encrypted value as new column, not separate table. So, choose what is more appropriate for you.

PL/SQL Replicating a table with a trigger on Oracle DB

I have never used triggers in PLSQL before, but I am now supposed to make a trigger that replicates the table of one database, and creates a copy of this table in another database. I am using AQT(Advanced Query Tool) as DBMS, and i have 2 database connections, and I need to copy the table and or data from DB1 to DB2. It's only based on one table that I need replicated, following tutorialspoint I have concluded that it should look somewhat like this:
`
CREATE OR REPLACE TRIGGER db_transfer
AFTER DELETE OR INSERT OR UPDATE ON X
WHEN (NEW.ID > 0)
I don't think i need for each since i want a copy of the whole table, and the condition is supposed to trigger this replication of the DB table. Is this the right approach?
EDIT
For anyone who uses AQT, they have a feature under Create -> Trigger -> and then click on the relevant tables etc to create it.

Customized Table Names in Sql Server

I have a table called Table 1. I'm trying to create an after-insert trigger for a Table 1; whereby, whenever a user enters a record, the trigger will create a new table named after the record that triggered its creation.
Please help, I'm using SQL Server 2008
This sounds super non-relational-database-design-ish. I would heavily advise against this in almost every case. And I say "almost" only to allow for artistic freedom of development, I can't think of a single case where this would be appropriate.
That said, if you do in fact want this, you can use dynamic SQL to create a table.
You can build the SQL in your trigger, but basically you want something like:
EXEC 'CREATE TABLE ' + #tableName + ' (ID INT IDENTITY(1,1))';
Of course, the columns are up to you, but that should get you started.
But while we're at it, what you should (probably) be doing is using a single table with a one-to-many relationship to the table on which your trigger is currently assigned.
For instance, if you have a table Users with a column for email and you're looking to create a table for each user's favorites on your website, you should instead consider adding an identity column for user IDs, then reference that in a single UserFavorites table that has UserId and PostId columns, and the appropriate foreign keys implemented.

Can dynamic SQL be called from a trigger in Oracle?

I have a dozen tables of whom I want to keep the history of the changes. For every one I created a second table with the ending _HISTO and added fields modtime, action, user.
At the moment before I insert, modify or delete a record in this tables I call ( from my delphi app ) a oracle procedure that copies the actual values to the histo table and then do the operation.
My procedure generates a dynamic sql via DBA_TAB_COLUMNS and then executes the generated ( insert into tablename_histo ( fields s ) select fields, sysdate, 'acition', userid from table_name
I was told that I can not call this procedure from a trigger because it has to select the table the trigger is triggered on. Is this true ? Is it possible to implement what I need ?
Assuming you want to maintain history using triggers (rather than any of the other methods of tracking history data in Oracle-- Workspace Manager, Total Recall, Streams, Fine_Grained Auditing etc.), you can use dynamic SQL in the trigger. But the dynamic SQL is subject to the same rules that static SQL is subject to. And even static SQL in a row-level trigger cannot in general query the table that the trigger is defined on without generating a mutating table exception.
Rather than calling dynamic SQL from your trigger, however, you can potentially write some dynamic SQL that generates the trigger in the first place using the same data dictionary tables. The triggers themselves would statically refer to :new.column_name and :old.column_name. Of course, you would have to either edit the trigger or re-run the procedure that dynamically creates the trigger when a new column gets added. Since you, presumably, need to add the column to both the main table and the history table, however, this generally isn't too big of a deal.
Oracle does not allow a trigger to execute a SELECT against the table on which the trigger is defined. If you try it you'll get the dreaded "mutating table" error (ORA-04091), and while there are ways to get around that error they add a lot of complexity for little value. If you really want to build a dynamic query every time your table is updated (IMO this is a bad idea from the standpoint of performance - I find that metadata queries are often slow, but YMMV) it should end up looking something like
strAction := CASE
WHEN INSERTING THEN 'INSERT'
WHEN UPDATING THEN 'UPDATE'
WHEN DELETING THEN 'DELETE'
END;
INSERT INTO TABLENAME_HISTO
(ACTIVITY_DATE, ACTION, MTC_USER,
old_field1, new_field1, old_field2, new_field2)
VALUES
(SYSDATE, strAction, USERID,
:OLD.field1, :NEW.field1, :OLD.field2, :NEW.field2)
Share and enjoy.