UPDATE OPENQUERY failure - mysql

I'm getting an error in the following OPENQUERY statement that I'm trying to execute against a MySql database from SQL Server.
UPDATE OPENQUERY(MYWPDB, 'SELECT total FROM wp_tt WHERE id = 112121') SET total = 1
The error is "Key column information is insufficient or incorrect. Too many rows were affected by update".
The statement should be updating the 'total' field to the value of '1'. It's an integer field and 'id' is the primary key on the table. I'm using SQL Server 2000.

I had the same issue with an openquery that updates iSeries. My openquery is within a cursor also.
The fix is to include the key columns in the select.
So in your case it would be something like this:
UPDATE OPENQUERY(MYWPDB, 'SELECT key1, key2, total FROM wp_tt WHERE id = 112121') SET total = 1

Turns out there's nothing wrong with the query. I was trying to execute the statement inside a cursor operation inside a stored procedure. I tested it outside the cursor operation and it processed fine.
However, since I still needed it to work within the cursor, I had to keep digging, and finally found the four-part syntax would do the trick. So the query instead became:
UPDATE MYWPDB...wp_tt SET total = 1 WHERE id = 112121

Related

MySql create record with IF statement

SQL Query Forum 20210309
I’m building a Firebase Functions application that talks to a Google Cloud SQL database running MySQL 5.7. I’m trying to retrieve a value from a row in one table and, if it exists (the row or the value), insert a record in a different table.
Based on some examples I found online, my code looks like this:
DECLARE meeting_link varchar(2048) DEFAULT ""; SELECT meeting_link from campaigns where id=2 INTO meeting_link; IF LENGTH(meeting_link) > 0 THEN INSERT INTO clicks (target_id, ip_address, user_agent) VALUES (38, "ip-address", "user-agent") END IF;
In all of the different versions of this I tried, I get an error:
You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'DECLARE meeting_link varchar(2048) DEFAULT ""; SELECT meeting_link from campaigns' at line 1
Looking around some more, I found posts that say I can’t use DECLARE in anything but stored procedures, but I can use local variables (#ml for example) but I can’t seem to get that working correctly either.
Can someone please help me with the SQL I need for this? I need to create the record only if the record in the query exists and return the meeting_link value to my calling program.
Refer to this documentation page:
https://dev.mysql.com/doc/refman/8.0/en/sql-compound-statements.html
This section describes the syntax for the BEGIN ... END compound statement and other statements that can be used in the body of stored programs
That includes DECLARE and also IF/THEN/ELSE/END constructions. You can't use those outside of stored routines.
Here's a trick you can use instead of a stored routine:
SELECT meeting_link from campaigns where id=2 INTO #meeting_link;
INSERT INTO clicks (target_id, ip_address, user_agent)
SELECT 38, 'ip-address', 'user-agent' FROM dual WHERE LENGTH(#meeting_link) > 0;
You can use #meeting_link which is a user-defined variable, not a declared local variable.
Then instead of using IF, use FROM dual WHERE ... for your condition. The dual table is normally a pseudo-table that doesn't really exist but querying it returns 1 row. But you can make that zero rows if the condition in the WHERE clause isn't satisfied.
So the INSERT will conditionally create either one or zero rows.
Re your comment:
If you need this to be done in a single SQL statement, then one option would be to make that single SQL statement CALL a procedure that you create in your MySQL database. Then at least you could use DECLARE and IF like you were intending.
Another alternative is to combine the two statements I show above like this:
INSERT INTO clicks (target_id, ip_address, user_agent)
SELECT 38, 'ip-address', 'user-agent'
FROM campaigns WHERE id=2 AND LENGTH(meeting_link) > 0;
This works because even though you query the campaigns table, it's not mandatory to select the columns of that table. You can select constant values instead. The conditions in the WHERE clause will make this return either one row or zero rows.

A variable is cut in a wrong way but now sure why?

I'm writing a script that locates all branches of a specific repo that haven't received any commits for more than 6 months and deletes them (after notifying committers).
This script will run from Jenkins every week, will store all these branches in some MySQL database and then in the next run (after 1 week), will pull the relevant branch names from the database and will delete them.
I want to make sure that if for some reason the script is run twice on the same day, relevant branches will not get added again to the database, so I check it using a SQL query:
def insert_data(branch_name):
try:
connection = mysql.connector.connect(user=db_user,
host=db_host,
database=db_name,
passwd=db_pass)
cursor = connection.cursor(buffered=True)
insert_query = """insert into {0}
(
branch_name
)
VALUES
(
\"{1}\"
) where not exists (select 1 from {0} where branch_name = \"{1}\" and deletion_date is NULL) ;""".format(
db_table,
branch_name
)
cursor.execute(insert_query, multi=True)
connection.commit()
except Exception as ex:
print(ex)
finally:
cursor.close()
connection.close()
When I run the script, for some reason, the branch_name variable is cut in the middle and then the query that checks if the branch name already exists in the database fails:
1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'where not exists (select 1 from branches_to_delete where branch_name = `AUT-1868' at line 8
So instead of checking for 'AUT-18681_designer_create_new_name_if_illegal_char_exist' it checks for 'AUT-1868' which doesn't exist in the database.
I've tried the following:
'{1}'
"{1}"
{1}
But to no avail.
What am I doing wrong?
Using WHERE statement in INSERT INTO query is illegal:
INSERT INTO `some_table`(`some_column`)
VALUES ('some_value') WHERE [some_condition]
So, the above example is not valid MySQL query. For prevent duplication of branch_name you should add unique index on your table like:
ALTER TABLE `table` ADD UNIQUE INDEX `unique_branch_name` (`branch_name`);
And after this you can use next query:
INSERT INTO `table` (`branch_name`) VALUES ('branch_name_1')
ON DUPLICATE KEY UPDATE `branch_name` = `branch_name`;
Pay attention: If your table have auto-increment id, it will be incremented on each insert attempt
Since MySQL 8.0 you can use JASON_TABLE function for generate pseudo table from your values filter it from already exists values and use it fro insert. Look here for example
I don't see anything wrong assuming the source of the branch_name is safe (you are not open to SQL Injection attacks), but as an experiment you might try:
insert_query = f"""insert into {db_table}(branch_name) VALUES(%s) where not exists
(select 1 from {db_table} where branch_name = %s and deletion_date is NULL)"""
cursor.execute(insert_query, (branch_name, branch_name))
I am using a prepared statement (which is also SQL Injection-attack safe) and thus passing the branch_name as a parameters to the execute method and have also removed the multi=True parameter.
Update
I feel like a bit of a dummy for missing what is clearly an illegal WHERE clause. Nevertheless, the rest of the answer suggesting the use of a prepared statement is advice worth following, so I will keep this posted.

Check if record exists delete it using mysql

i'm using MySQL and i want to check if a record exists and if it exists delete this record.
i try this but it 's not working for me:
SELECT 'Barcelone' AS City, EXISTS(SELECT 1 FROM mytable WHERE City = 'Barcelone') AS 'exists';
THEN
DELETE FROM mytable
WHERE City = 'Barcelone';
Thank you for your help.
The if statement is only allowed in stored procedures, stored functions, and triggers (in MySQL).
If I understand what you want, just do:
DELETE FROM mytable
WHERE City = 'Barcelone';
There is no reason to check for the existence beforehand. Just delete the row. If none exist, no problem. No errors.
I would recommend an index on mytable(city) for performance reasons. If you want to check if the row exists first, that is fine, but it is unnecessary for the delete.
If you mean MySQL is returning an error message (if that's what you mean by "not working for me"), then that's exactly the behavior we would expect.
That SQL syntax is not valid for MySQL.
If you want to delete rows from a table, issue a DELETE statement, e.g.
DELETE FROM mytable WHERE City = 'Barcelone'
If you want to know how many rows were deleted (if the statement doesn't throw an error), immediately follow the DELETE statement (in the same session) with a query:
SELECT ROW_COUNT()
Or the appropriate function in whatever client library you are using.
If the ROW_COUNT() function returns 0, then there were no rows deleted.
There's really no point (in terms of MySQL) in issuing a SELECT to find out if there are rows to be deleted; the DELETE statement itself will figure it out.
If for some reason your use case requires you to check whether there are rows be be deleted, then just run a separate SELECT:
SELECT COUNT(1) FROM mytable WHERE City = 'Barcelone'

How to neglect "Invalid column name" error in SQL Server 2008 R2

I am using SQL Server 2008 R2. I have created some SQL statements for some migration:
IF EXISTS (SELECT 1 FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME='TableA' AND COLUMN_NAME='Status')
BEGIN
UPDATE TableA
SET Status = 'Active'
WHERE Status IS NULL
END
Now, I have dropped the column Status from database table TableA.
Again when I am executing the above block, and although I have placed a check whether that column exists, only then it should execute the UPDATE statement, it gives me error
Invalid column name 'Status'
How to get rid of this error?
Thanks
You need to put the code to run in a separate scope/batch:
IF EXISTS (SELECT 1 FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME='TableA' AND COLUMN_NAME='Status')
BEGIN
EXEC('UPDATE TableA SET Status=''Active'' WHERE Status IS NULL')
END
The problem you currently have is that the system wants to compile your batch of code before it executes any part of it. It can't compile the UPDATE statement since there's a column missing, so it never even has a chance to start executing the code and considering whether the EXISTS predicate returns true or false.
Your current SQL Block might fail some times because Information_schema is view and not a table. Also, according to MSDN
Some changes have been made to the information schema views that break backward compatibility.
Hence we can't rely on information schema views.
Instead use sys.tables
IF EXISTS(SELECT 1 FROM SYS.COLUMNS
WHERE NAME = N'Status' AND OBJECT_ID = OBJECT_ID(N'TableA'))
BEGIN
UPDATE TableA SET Status='Active' WHERE Status IS NULL
END

Looking for solution in case statement in SQL Server

I am trying to write this below statements in case statements. Trying to update a value in one different TableB for a particular column.
After I do
Update a
set DISMMR =
then trying to check this below condition in case statements
'H01' Is not NULL
and
('H02','H03','HR04','S07','S08','S09') Is NULL
Then 'Unknown'
Here this values are from table name : TableA and column name is Code.
This particular column is designed to be NOT NULL
Here where I say Is NULL means I am trying to say that, this particular value ('H02','H03','HR04','S07','S08','S09') don't exist or present in TableA.
When I say this particular value H01 in TableA for column Code ---- Is not NULL -- means this particular value of column Code exist/present in a column from TableA.
I need to do this one in case statements because once I am done checking this condition , I am writing other case statements started with WHEN to check another condition and update with different value
I am using SQL Server 2008 R2. Now I wrote the below query. It runs fine in SSMS but when i use this Store procedure in SSIS package. My package fails with error.
[Execute SQL Task] Error: Executing the query "execute [dbo].[usp_GetMRF_CHP] ?,?,?" failed with the following error: "Only one expression can be specified in the select list when the subquery is not introduced with EXISTS.". Possible failure reasons: Problems with the query, "ResultSet" property not set correctly, parameters not set correctly
CASE WHEN EXISTS(SELECT 1 FROM dbo.TableA WHERE Code = 'H01')
AND NOT EXISTS(SELECT 1 FROM dbo.TableA
WHERE Code IN ('H02','H03','HR04','S07','S08','S09')
)
THEN 'Unknown'
when ---- I have another case here.
Any help will be very much appreciated. Thanks in advance
If I understand you correct you want to know if a record with Code = 'H01' exists while no record with the other codes exist. The case statement for that would look like this:
CASE WHEN EXISTS(SELECT 1 FROM dbo.TableA WHERE Code = 'H01')
AND NOT EXISTS(SELECT 1 FROM dbo.TableA
WHERE Code IN ('H02','H03','HR04','S07','S08','S09')
)
THEN 'Unknown'
END