How to combine 8 queries into one to create a procedure? - mysql

I have a table I created to match an online Template for uploading inventory to Amazon. In total, it has 440 columns. I'm not worried about that, and neither are they, it is mostly necessary. It pulls from two other tables that I'll call table1 and table2. I'll call the other one templateTable.
Basically, I'm starting with a TRUNCATE to completely wipe the information on the templateTable. I want it empty when it gets filled, for no reason other than it makes me feel comfortable. No other table gets truncated, just this table every time the query is run.
After that, there is a massive INSERT query that takes info from table1 and table2 and puts all of that into templateTable's specific columns.
Query 3 is an update at this point, and so is pretty much queries 3 - 8. They're all update queries. I did them separately from the second query, where everything gets populated, because each update has a CASE and different requirements.
I wanted to create a procedure for these queries so they could just run the one procedure and call it a day. But I'm uncertain how to combine the 8 queries that fill and correct the information in this templateTable. I should mention I'm not just taking info from one table and sticking it in the templateTable- it is more like "case when table1.modelNum = 1234 then templateTable.modelNum = 5678".

You can wrap all of your 8 SQL statements inside of a procedure in MySQL like this:
CREATE PROCEDURE MyProcedure()
BEGIN
<SQL STATEMENT 1>;
<SQL STATEMENT 2>;
<SQL STATEMENT 3>;
<SQL STATEMENT ...>;
END//
Then to call it you submit:
exec MyProcedure;

Related

Select Into/Insert Into SQL Server query duplicates

Sorry for asking this question, but I am a beginner in SQL, my colleague at work build a view, which I need as datasource for a report, however since this view is based on several other views it takes like 45 minutes to execute the query. This is way to long. Therefore I created a table from that view, initial execution time is the same, but once in place it executes in seconds.
In Microsoft SQL Server 2014 I used the following query:
select *
into [dbo].[MAT_v_demnew_daily_am_all_data]
from [dbo].[v_demnew_daily_am]
This works fine, but since the view is updated daily I also need to refresh the table everyday. When I now execute the above mentioned query I get the message that the table already exists.
That's why I tried to use 'insert' in this case:
insert into [dbo].[MAT_v_demnew_daily_am_all_data]
select *
from [dbo].[v_demnew_daily_am]
Here I have the problem that it not only inserts the additional data but also the already existing data, so in the end I have duplicates.
As a workaround I now manually delete the [dbo].MAT_v_demnew_daily_am_all_data] table and then execute the select * into query.
Now I am looking for an easier solution, is it possible to having the table deleted by query and in the same query create a new one by select * into or is it possible to only insert new data from the view to the table so that I don't get duplicates.
Moreover, is it possible to have such SQL statement being executed automatically on a daily basis, maybe by .bat file and windows task scheduler?
I know that the source of all problems is the View and that we should improve that, but looking for a short term solution first.
Thanks so much.
Mathias
Try this:
IF OBJECT_ID('dbo.MAT_v_demnew_daily_am_all_data', 'U') IS NOT NULL
DROP TABLE dbo.MAT_v_demnew_daily_am_all_data
SELECT INTO dbo.MAT_v_demnew_daily_am_all_data FROM dbo.v_demnew_daily_am
This query is reusable on a daily basis.
You can create one stored procedure including this query.
Then you only need to execute the stored procedure.
Updated
Before you create the stored procedure, please check if you have the permission.
Then try:
create procedure [procedure_name]
as
IF OBJECT_ID('dbo.MAT_v_demnew_daily_am_all_data', 'U') IS NOT NULL
DROP TABLE dbo.MAT_v_demnew_daily_am_all_data
SELECT INTO dbo.MAT_v_demnew_daily_am_all_data FROM dbo.v_demnew_daily_am;
After you create it:
EXEC [procedure_name];

Oracle Trigger: How to put OLD and NEW values as JSON for multiple tables

I'm wondering if this is possible in Oracle 12g to make a procedure that will be called on update from triggers on multiple tables with different columns.
From my understanding I got two values OLD and NEW. I'm making trigger that work AFTER UPDATE & FOR EACH ROW. Does this possible to send whole row ( variables :OLD or :NEW) to some function like JSON_OBJECT or etc. which will parse row and produce output that can be stored in some audit table?
Main reason for such needs is to not keep in every trigger their own list of columns names for table. Because it different and every change in every table structure will affect trigger.
Or maybe I'm wrong and you can suggest how to properly solve this?
For test cases I have something like this:
AUDIT_TBL (ID, TABLE_NAME,OLD_JSON,NEW_JSON,DATE);
TABLE1 (ID,KEY,VALUE);
TABLE2 (ID,NAME,SURNAME,KEY);
TABLE3 (KEY,COLUMN1,CLOMUNT2,COLUMN3);
I was planning to have trigger on TABLE1,TABLE2,TABLE3 that will run some procedure with parameters as row (:OLD or :NEW), will get a result and put it into AUDIT_TBL.
Any suggestions or ideas how to do this properly and without blood?

How can I sum two fields and store the result in a third field on a MySQL table autonomously?

I created a simple UPDATE AFTER INSERT trigger to sum two DECIMAL(10,2) fields and update a 3rd DECIMAL(10,2) field with the summed value.
The trigger code is:
delimiter |
CREATE TRIGGER calc_ttl_cost AFTER INSERT ON buybox_rec
FOR EACH ROW
BEGIN
UPDATE buybox_rec SET total_cost = (price+shipping_cost);
END;
|
I'm using phpMyAdmin to run the SQL commands, so I know that the trigger is being created successfully. Furthermore, if I run the UPDATE buybox_rec SET total_cost = (price+shipping_cost); SQL statement alone, it works as expected. (I've also tried the same code with back-ticks around the field names, but I wouldn't be writing all this if that worked)
The problem is that when I insert a new row, the trigger doesn't work and this error is thrown:
#1442 - Can't update table 'buybox_rec' in stored function/trigger
because it is already used by statement which invoked this stored
unction/trigger.
The error seems like some sort of recursive or circular reference problem, but I can't figure out where/what the problem is.
I also tried creating a stored procedure and calling it from within the trigger to try obtaining the same result, but I got the same error.
I checked a bunch of other SO questions related to MySQL UPDATE triggers and did some Googling, but here I am.
Is this out of the scope of MySQL? It seems like such a common and easy task to allow for.
Does anyone know how I accomplish this task autonomously? (AKA I don't want to hear about summing the fields after the fact via PHP, for example)
THanks for any help
The problem is that you're trying to modify the contents of a table which is already being used by the UPDATE + TRIGGER operation. This simply can't be done, but you have alternatives.
For example, if your meaningful data (or independent variables) are price and shipping cost while the total cost depends on them, you could keep only the first two in your table, and maybe have a very simple VIEW (something like SELECT price, shipping_cost, price+shipping_cost total_cost FROM buybox_rec, or whichever other fields you need) if you want to keep an eye at the total.

No data if queries are sent between TRUNCATE and SELECT INTO. Using MySQL innoDB

Using a MySQL DB, I am having trouble with a stored procedure and event timer that I created.
I made an empty table that gets populated with data from another via SELECT INTO.
Prior to populating, I TRUNCATE the current data. It's used to track only log entries that occur within 2 months from the current date.
This turns a 350k+ log table into about 750 which really speeds up reporting queries.
The problem is that if a client sends a query precisely between the TRUNCATE statement and the SELECT INTO statement (which has a high probability considering the EVENT is set to run every 1 minute), the query returns no rows...
I have looked into locking a read on the table while this PROCEDURE is ran, but locks are not allowed in STORED PROCEDURES.
Can anyone come up with a workaround that (preferably) doesn't require a remodel?
I really need to be pointed in the right direction here.
Thanks,
Max
I'd suggest an alternate approach instead of truncating the table, and then selecting into it...
You can instead select your new data set into a new table. Next, using a single RENAME command, rename the new table to the existing table and the existing table to some backup name.
RENAME TABLE existing_table TO backup_table, new_table TO existing_table;
This is a single, atomic operation... so it wouldn't be possible for the client to read from the data after it is emptied but before it is re-populated.
Alternately, you could change your TRUNCATE to a DELETE FROM, and then wrap this in a transaction along with the SELECT INTO:
START TRANSACTION
DELETE FROM YourTable;
SELECT INTO YourTable...;
COMMIT

Can I launch a trigger on select statement in mysql?

I am trying to run an INSERT statement on table X each time I SELECT any record from table Y is there anyway that I can accomplish that using MySQL only?
Something like triggers?
Short answer is No. Triggers are triggered with INSERT, UPDATE or DELETE.
Possible solution for this. rather rare scenario:
First, write some stored procedures
that do the SELECTs you want on
table X.
Then, restrict all users to use only
these stored procedures and do not
allow them to directly use SELECT on table
X.
Then alter the stored procedures to
also call a stored procedure that
performs the action you want
(INSERT or whatever).
Nope - you can't trigger on SELECT - you'll have to create a stored procedure (or any other type of logging facility - like a log file or what ever) that you implicitly call on any query statement - easier if you create a wrapper that calls your query, calls the logging and returns query results.
If you're trying to use table X to log the order of SELECT queries on table Y (a fairly common query-logging setup), you can simply reverse the order of operations and run the INSERT query first, then run your SELECT query.
That way, you don't need to worry about linking the two statements with a TRIGGER: if your server crashes between the two statements then you already logged what you care about with your first statement, and whether the SELECT query runs or fails has no impact on the underlying database.
If you're not logging queries, perhaps you're trying to use table Y as a task queue -- the situation I was struggling with that lead me to this thread -- and you want whichever session queries Y first to lock all other sessions out of the rows returned so you can perform some operations on the results and insert the output into table X. In that case, simply add some logging capabilities to table Y.
For example, you could add an "owner" column to Y, then tack the WHERE part of your SELECT query onto an UPDATE statement, run it, and then modify your SELECT query to only show the results that were claimed by your UPDATE:
UPDATE Y SET owner = 'me' WHERE task = 'new' AND owner IS NULL;
SELECT foo FROM Y WHERE task = 'new' AND owner = 'me';
...do some work on foo, then...
INSERT INTO X (output) VALUES ('awesomeness');
Again, the key is to log first, then query.