DB2 SQL - Cannot successfully insert into table after trigger has been made - sql

I have been running into problems inserting values into a table after having a trigger attached to it.
The trigger is the following:
CREATE TRIGGER trig
AFTER INSERT ON Follows
REFERENCING NEW as N
FOR EACH row
WHEN ((Select email from Celebrity) <> N.followed_email)
UPDATE followSuggestion SET followSuggestion.Suggested_follower = N.followed_email, followSuggestion.Suggested_followee = N.follower_email
;
the insert code is the following:
INSERT INTO follows
VALUES('Michael_Phelps#uss.net','Michael_Phelps#uss.net');
And the error is as follows
DB21034E The command was processed as an SQL statement because it was not a
valid Command Line Processor command. During SQL processing it returned:
SQL0811N The result of a scalar fullselect, SELECT INTO statement, or VALUES
INTO statement is more than one row. SQLSTATE=21000
SQL0811N The result of a scalar fullselect, SELECT INTO statement, or VALUES INTO statement is more than one row.
Thank you in advanced!

I think this is the problem:
(Select email from Celebrity) <> N.followed_email
The subquery will probably return more than one row so the scalar operator <> will not work.
You will have to rephrase that condition to something like:
WHEN ((Select COUNT(email) from Celebrity WHERE email = N.followed_email) = 0) ...

Related

INSERT error in Oracle

I am working with oracle (with Toad) but when I try to execute this query
INSERT INTO KEYUSER(NAME) VALUES(UNAME) WHERE ID = 1;
I get this error:
SQL command not properly ended. Found 'WHERE' expecting ;-or- LOG -or- RETURN RETURNING
What is wrong? Regards.
You can never use where clause in insert statement. It does not make any sense to have it while you are simply trying to insert a row.
General Insert statement is like below
INSERT INTO table_name (column1, column2, column3, ...)
VALUES (value1, value2, value3, ...);
So in your case you have to remove where clause from your statement and query will be like below
INSERT INTO KEYUSER(NAME) VALUES('UNAME');
Presumably, you intend an UPDATE rather than INSERT:
UPDATE KEYUSER
SET NAME = UNAME
WHERE ID = 1;
Sometimes new users of SQL get confused between INSERT and UPDATE. INSERT inserts new rows into a table. UPDATE changes values in existing rows. The confusion is become some people interpret INSERT as "inserting new values into a row".

Stored Procedure

I am using SQl-server 2012 and this code is inside in a Stored Procedure.
These are my SQL queries.I want to execute "Insert" query when "Update" query not executed.
If Update query executed,then insert query should not be executed.
Update tblStock Set Balance= Balance + #ReduceRawQty
Where LocCode=#LocCode
AND ItemCode=#rawitemcode
and CostPrice=#rawcostprice
Insert Into tblStock(LocCode, ItemCode, CostPrice, Balance,Transfer,PCode)
Values(#LocCode,#rawitemcode,#RawCostPrice,#RawQty,0,#PCode)
Is there any method to do this ,please help me
You can check ##ROWCOUNT to see how many rows were affected by the UPDATE statement:
UPDATE ...
IF ##ROWCOUNT = 0
INSERT ...
Alternatively you can use EXISTS to check for a row first and decide which operation to perform:
IF EXISTS (SELECT 1 FROM tblStock WHERE LocCode=#LocCode AND ItemCode=#rawitemcode and CostPrice=#rawcostprice)
UPDATE ...
ELSE
INSERT ...

Fetch a row via ODBC when there are 2 SQL statements: insert and select

I can't fetch a row in a query like this:
INSERT INTO ...;
SELECT ...;
The query in correct and the INSERT statement succeed, but SQLFetch returns false.
If I remove the INSERT statement and leave only the SELECT, SQLFetch returns true and everything is OK.
I use SQLExecDirect to execute a query and SQLFetch to fetch.

How to avoid launching a trigger for every row of a prepared statement?

I have a FOR EACH STATEMENT trigger on table1:
CREATE TRIGGER trg_table1 AFTER INSERT OR DELETE OR UPDATE OF field1 ON table1
FOR EACH STATEMENT EXECUTE PROCEDURE my_trigger_procedure();
I have to update rows of that table as follows:
UPDATE table1 SET field1='abc' WHERE field5=1;
UPDATE table1 SET field1='def' WHERE field5=2;
UPDATE table1 SET field1='ghi' WHERE field5=3;
...
Names and values are simplified for clarity.
Each UPDATE is considered a single statement, so the trigger is fired for every one of those rows.
To avoid that, I made a prepared statement:
PREPARE my_prep_stmnt AS
UPDATE table1
SET
field1=$1
WHERE field5=$2
;
EXECUTE my_prep_stmnt ('abc',1);
EXECUTE my_prep_stmnt ('def',2);
EXECUTE my_prep_stmnt ('ghi',3);
I was expecting the trigger to be fired only after the prepared statement was done, but no, the trigger is fired for every EXECUTE row.
The problem is that the trigger procedure takes time to execute.
Any idea to go around this ?
Provide multiple rows in a subquery with a VALUES expression to make it a single UPDATE statement:
UPDATE table1 t
SET field1 = u.field1
FROM (
VALUES
('abc'::text, 1) -- cast string literal in row 1 to make type unambiguous
,('def', 2)
,('ghi', 3)
) u (field1, filed5)
WHERE t.field5 = u.field5;
You need to cast to a matching type, since the VALUES expressions stands alone and cannot derive the column type like in the UPDATE. Unquoted numbers with just digits default to integer (bigint / numeric if too big).
You can still use a prepared statement (with many parameters). For a large number of rows rather switch to bulk loading to a temporary staging table and update from there:
How to update selected rows with values from a CSV file in Postgres?
More options:
How to UPDATE table from csv file?

Sql update statement, any way of knowing what it actually did?

Typically, I test an update by running a query using the where statement and then after verifying that it does what I think I want it to copying the where clause to the update statement and executing it. But is there any way of getting the statement to return what the update did besides the '4 rows updated'
Sure, take a look at the output clause of T-SQL
http://msdn.microsoft.com/en-us/library/ms177564.aspx
You could load your records into a temp table/variable in SQL Server:
DECLARE #Temp TABLE(ID INT)
INSERT INTO #Temp (ID)
SELECT ID
FROM Customer
WHERE AcctBalance > 5000
--inspect as needed
UPDATE Customer
SET AcctBalance = 0
WHERE ID IN (SELECT ID FROM #Temp)
That depend in the server, library that you use, in php, pdo exec return number of row effected by delete or update cluase