Issues deleting a row using OPENQUERY() with RPC enabled, obeying case sensitivity - mysql

I'm using T-SQL and I want to delete a row from a linked server using MYSQL.
For this I've tried:
delete from openquery(MYSQLServer,
'select * from dTable where date = cast(cast(date_add(now(),interval -6 day)as date) as int)
and ProductKey = 38410 and StoreKey = 3201')
But this gives the error
There was a recoverable, provider-specific error, such as an RPC failure.
I then Googled this issue and realized that I need to adjust the RPC settings in management studios by right clicking the linked server and set RPC = True and RPC Out = True. Refreshing the linked servers and executing the Query again yield the same error.
From searching the web I've also realized that delete is case sensitive.
However, using
exec sp_tables_ex MYSQLServer
showed me that I use the exact same case on the table. I've also controlled that each column has the same case. I've tried to rewrite the Query to have only upper case values just in case, but then I got the error that the table with uppercase does not exist.
I've also tried to use
SELECT * FROM MYSQLServer.Catalog.dbo.dTable
but that gave the error Invalid object name.
I've also tried:
select * from openquery(MYSQLServer,
'delete from dTable where date = cast(cast(date_add(now(),interval -6 day)as date) as int)
and ProductKey = 38410 and StoreKey = 3201')
but this gave the error that either object has no columns, or the current user does not have permissions on that object.
Does anyone have any clue?
EDIT
I've found that Another linked server, from which I have successfully deleted a row earlier, had a user name with a remote userID and password defined under Security settings at the specific Linked Server in management studios.
I tried to mimic this by using:
EXEC sp_addlinkedsrvlogin 'MYSQL_UNIC', 'false', 'uid', 'rmtid', 'rmtpw'
but this gives me the error
Access denied for user rmtid (using password: YES)
when I try to use the delete Query.
I'll try to find how to get permission to Query using a remote user.

Here’s the solution:
Make sure the RPC and RPC Out are set to TRUE on the LinkedServer’s properties.
Then use the following syntax (This is specifically for Teradata):
declare #SQL varchar(1000)
SET #SQL = ‘DELETE FROM DB.tableName ALL’
EXEC (#SQL) AT TERADATA_LINKEDSERVER

Related

sqlcmd on Azure SQL Data Warehouse - SqlState 24000, Invalid cursor state after INSERT statement

I am working on a script to reload a table using SQLCMD on Linux connecting to an Azure SQL Data Warehouse database.
After the INSERT statement completes, the next statement fails (but does not end the sqlcmd execution) with the "warning"
insert into
schema.table_temp
(
...list of columns
)
select
...list of columns
from
schema.table
;
GO (COMMENT--> in script, but not echoed in log.)
(0 rows affected)
IF EXISTS (SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES t WHERE TABLE_TYPE = 'BASE TABLE' and TABLE_SCHEMA = 'schema' AND TABLE_NAME = 'table_nox' )
DROP TABLE schema.table_nox
;
GO (COMMENT--> in script, but not echoed in log.)
SqlState 24000, Invalid cursor state
The script continues to run with each subsequent batch getting the same
SqlState 24000, Invalid cursor state "warning"
If I comment out the INSERT statement, the script runs without warning as expected. I speculate the INSERT statement is not closing a cursor and then subsequent commands get the warning which should really be considered an eror and end the execution. (I have the -b flag on in the sqlcmd invocation.)
Is my only solution to break the script into multiple parts?
this seems to be an issue with the ODBC Driver that is used by sqlcmd under the hood. Can you confirm if you see this issue with Azure SQL DB? It would also be good to see your odbc.ini and odbcinst.ini files. Can you share those out?
In the meanwhile, I would like to recommend a couple of very cool Node.js command line tools that are more suited for Linux and Mac environments:
SQL-CLI
Cheetah
Thanks,
Meet
I faced similar issue and adding GO between two statements helped me.
We had the same issue. When performing INSERT via a SELECT it resulted in a (0 rows affected) response and a invalid cursor state error. Adding SET NOCOUNT ON at the start of the script worked for us. As #meet-bhagdev has already pointed out it looks like a driver issue.

Invalid descriptor index on LAST_INSERT_ID after insert

Strange situation with my ODBC code ( called from a C library ). Basically, I have the following sequence of events:
Create insert statement ( just a string )
Call SQLPrepare with that insert statement string
Bind the various parameters ( column values ), using
SQLBindParameter
Call SQLExecute to insert the row ( this works, by the way, as I can
see the row in the MySQL DB )
Create "select last_insert_id()" statement string
NOTE: if in SQL Server mode, we would create a "select ##identity"
statement
Bind column using SQLBindCol - this is where I get the "Invalid
descriptor index" error
NOTE: if in SQL Server mode, this works fine, with no error
Call SQLExecDirect to get the last insert id - this never happens
because of SQLBindCol error
Does the standard MySQL ODBC connector require something special in this situation? Does anyone have an ODBC example of this type of "insert" then "get last insert id" behavior? Maybe I need to call "SQLPrepare" before step 6 ( where I bind the column )? Another way to ask this: Should there be an SQLPrepare call for each SQLExecute or SQLExecDirect call?
I know it works directly in SQL, so the problem is my C ODBC code.
Thanks.
For those who are interested, I ended up changing the above steps by adding an SQLPrepare call between creating the "select last_insert_id()" ( step 5 ) and calling SQLBindCol ( step 6 ). Not sure if that would work for others, but it seems to be working rather well for me.
As for research, I looked all over the place online and never found a really good or clear answer. Most comments were about the SQL involved, not ODBC. And the references to ODBC were vague and did not seem to apply to my situation, from what I could see.
My assumption is that the SqlServer ODBC driver I am using handles the missing prepare statement differently ( maybe even better, but that is debatable ) than my MySql ODBC driver.
SQL Server ODBC driver was the one provided by Easysoft
MySql ODBC driver was the one provided with the standard CentOS install of MySql
Hopefully this will help people. Obviously, if people have a better idea, please tell us.

Storing values in variables using Execute SQL Task Object

I have an execute sql task defined in my package which will execute a stored procedure. When the stored procedure is executed it will return user credential. I have to store the credential in a variables and then use these credentials in a new script task.
The following is what I have tried so far.
STEP 1 - I have created SQL task
On General TAB set following properties:
Resultset: Single row
connectionType: OLE DB
Connection:SourceDestination
SQLSourceType:DirectInput
SQLStatement: Execute dbo.GetLoginInfo1
ByPassPrepare = False
STEP 2 - Parameter Mapping Tab
Variable Name = User::DatabaseUserName
Direction = Output
Data Type = NVarchar
Parameter Name = #UserId
Parameter Size = 50
STEP 3 - Result Set tab
Result Name = 0
Variable Name = User::DatabaseUserName
When I executed the task I got following errors.
[Execute SQL Task] Error: Executing the query "EXECUTE [dbo].[GetUserLoginInfo1]"
failed with the following error: "Value does not fall within the expected range."
Possible failure reasons: Problems with the query, "ResultSet" property not set
correctly, parameters not set correctly, or connection not established correctly
When I debug I got to see following information:
Break ON Pre execute:
User::DatabaseUserName = {Hi}
Break ON Post Execute: (error happens but the values gets chanage)
User::DatabaseUserName = {User1}
Sorry just forgot to mention the creation of variables. I have create one variable as listed below.
Name = DatabaseUserName
Scope = Package1
Datatype = String
Value = Hi
The below mentioned is the stored procedure that I have used.
ALTER PROCEDURE [dbo].[GetUserLoginInfo1]
AS
BEGIN
SELECT userid AS userid
FROM login_credentials
WHERE servername= 'server1'
END
I have tried and read lot many sites but I am still facing the problem.This is my second day on it and have to resolve it before tomorrow morning so any help will be really appreciated.
You should completely omit STEP2. (However, your procedure does not have any output column.)
STEP 1, and STEP 3 are all right. (In STEP 3 you could use userid in the Result Name column of the grid, but the ordinal will be absolutely good.)

Does SQL Server Management Studio (or SQL Server) evaluate *all* expressions?

Here's my configuration:
I have a re-runnable batch script that I use to update my database.
Inside of that batch script, I have code that says the following:
If Table 'A' doesn't exist, then create Table 'A' and insert rows into it.
Later on in that batch script, I create an schemabound indexed view on that table.
And if you didn't already know, indexed views require specific client settings.
Sometimes, when I re-run the script, that is after the table has been created, SQL Server Management Studio evaluates the "insert rows" code, which is protected by the 'If this table doesn't exist' code, and yields the following error:
Msg 1934, Level 16, State 1, Line 15
INSERT failed because the following SET options have incorrect settings: 'CONCAT_NULL_YIELDS_NULL, ANSI_WARNINGS, ANSI_PADDING, ARITHABORT'. Verify that SET options are correct for use with indexed views and/or indexes on computed columns and/or filtered indexes and/or query notifications and/or XML data type methods and/or spatial index operations.
Please note: If someone were to try this INSERT statement in a vacuum, I would fully expect SSMS to generate this error.
But not when it's protected by a conditional block.
My Question:
Does the SSMS compiler evaluate all expressions, regardless of whether they will actually be executed?
Yes, it evaluates all of them,take a look at this
declare #i int
select #i =1
if #i = 1
begin
declare #i2 int
set #i2 = 5
end
else
begin
declare #i2 int
set #i2 = 5
end
Msg 134, Level 15, State 1, Line 12
The variable name '#i2' has already been declared. Variable names must be unique within a query batch or stored procedure.
Another example with temp tables is here: What is deferred name resolution and why do you need to care?
your only way out would be to wrap it inside dynamic SQL
Note that most of the settings you mention are connection-level, i.e. in case you set/change them they stay in effect unless you close the connection or explicitly change their value.
Returning to your question. The error you mention looks like runtime error, i.e. the INSERT is actually being executed. It would be better if you could show your script (omitting details, but keeping batches).
Edit: it is not SSMS compiler that evaluates SQL you try to execute - it is SQL Server. What do you meant by 'evaluate'? Is it 'execute'? When you run a batch (which is what actually is being executed by a server), SQL Server first does syntactic analysis and throws error in case it finds any syntactic error, nothing is being executed at this point of time. In case syntax is ok, the server starts executing you batch.
Again, the error you show seems to be runtime - so I guess you'd carefully watch for the conditions and track what happens (or provide us more details about 'sometimes').

Issue calling a MySQL stored procedure (with params) via a linked server (SQL Server 2005) using OPENQUERY syntax

I'm having issues when trying to call a MySQL (5.0.77) stored procedure with parameters, via a linked server (SQL Server 2005) using the OPENQUERY syntax.
The MySQL stored procedure returns a result set, and when I use the 'EXEC ... AT ...' syntax the call works fine, e.g...
EXEC('CALL my_stored_proc(''2009-10-07'',''2009-10-07'');') AT MySQLSERVER;
The limitation of using 'EXEC ... AT ...' means I can't insert the result set into a temporary table in SQL Server, which is ultimately what I want to do. Which led me to trying the OPENQUERY syntax...
SELECT * FROM OPENQUERY(MySQLSERVER,'CALL my_stored_proc(''2009-10-07'',''2009-10-07'');')
...But this fails, and returns...
Msg 7357, Level 16, State 2, Line 1
Cannot process the object "CALL my_stored_proc(''2009-10-07'',''2009-10-07'');". The OLE DB provider "MSDASQL" for linked server "MySQLSERVER" indicates that either the object has no columns or the current user does not have permissions on that object.
Which is strange, given that the 'EXEC ... AT ...' call didn't complain about permissions. The following calls all work fine...
EXEC('SHOW TABLES;') AT MySQLSERVER;
SELECT * FROM OPENQUERY(MySQLSERVER,'SHOW TABLES;');
CREATE TABLE #tmpTest (
[table] varchar(255) null
);
INSERT INTO #tmpTest ([table])
SELECT * FROM OPENQUERY(MySQLSERVER,'SHOW TABLES;');
SELECT * FROM #tmpTest;
DROP TABLE #tmpTest;
So my question is, how can I make a call to a MySQL stored procedure, via a linked server, and store the result set in a temporary table in SQL Server? Either by using the 'EXEC ... AT ...' syntax, or by solving the object/permissions error when using the OPENQUERY syntax.
Any help would be greatly appreciated!
You need to enable "Ad Hoc Distributed Queries" on the SQL Server. This is not enabled by default, for security reasons. Most of the time, the "do not have permission" errors are related to this one.
Execute this on the SQL Server, and then try again your code:
EXEC sp_configure 'show advanced options', 1;
GO
RECONFIGURE;
GO
EXEC sp_configure 'Ad Hoc Distributed Queries', 1;
GO
RECONFIGURE;
GO
I hope it helps.
I tried the fix to configure "Ad Hoc Distributed Queries" but was still getting this same error:
"The OLE DB provider "MSDASQL" for linked server "MyMySQL" indicates
that either the object has no columns or the current user does not
have permissions on that object."
I am attempting a simple remote SELECT query against a linked MySQL database.
In my case, the query I was attempting looked like this. Pay attention to the number of lines used:
SELECT * FROM OPENQUERY
([MyMySQL],
'
SELECT
ID as ISSUE_ID, etc..
The fix was to remove the newline after the opening single-quote. Simple, huh? But not obvious.
The working code shown below:
SELECT * FROM OPENQUERY
([MyMySQL],
'SELECT
ID as ISSUE_ID, etc..
Hope it helps!
Rob
I realize this a pretty old post, but my problem was similar to Rob's in that the SQL within the OPENQUERY doesn't take line breaks as whitespace the same way SQL server does.
i.e. Laying out my query as follows:
SELECT
*
FROM
OPENQUERY(LINKEDSERVER, '
SELECT
SomeField
FROM
SomeTable
')
I needed to have spaces as if it were written on one line (using _ as a visible space for demonstration):
SELECT
*
FROM
OPENQUERY(LINKEDSERVER, '
SELECT_
SomeField_
FROM_
SomeTable
')