SQL Job error with OPENQUERY - sql

I am trying to run a SQL job with this TSQL script, and the following error is raised. The code runs well in a query window!
What is the problem with this code in the sql job?
SELECT *
FROM OPENQUERY("192.168.1.1",'SET FMTONLY OFF; EXEC spNewTest #Param1 = ''Test1''')
Error Message:
Executed as user: DOMAIN\USER. Incorrect syntax near '192.168.1.1'. [SQLSTATE 42000] (Error 102)
Regards,
Elio Fernandes

Use this
SELECT * FROM OPENQUERY('192.168.1.1','SET FMTONLY OFF; EXEC spNewTest #Param1 = ''Test1''')
instead of this
SELECT * FROM OPENQUERY("192.168.1.1",'SET FMTONLY OFF; EXEC spNewTest #Param1 = ''Test1''')
EDIT: The difference between simple comma and double comma is that the second one isn't use it in SQL Server, this post from Vineet in 2010 can support the answer
What is the difference between single and double quotes in SQL?
Thanks Charlie Fish for the observation

I just replaced the double quotes with squares brackets [192.168.1.1] and the job is running as expected.
Thanks.

Related

How can I validate SQL query syntax in oracle database?

set NOEXEC ON;
Select * from emp;
Set NOEXEC OFF;
This validation is working in SQL Server. But It's not working in oracle.
Is there any syntax to check the query is valid or not in Oracle.
Using EXPLAIN PLAN
EXPLAIN PLAN FOR SELECT FROM emp;
ERROR at line 1: ORA-00936: missing expression
EXPLAIN PLAN FOR SELECT * FROM emp;
Explained

How to rename something in SQL Server that has square brackets in the name?

I have a column in one of my tables which has square brackets around it, [Book_Category], which I want to rename to Book_Category.
I tried the following query:
sp_rename 'BookPublisher.[[Book_Category]]', 'Book_Category', 'COLUMN'
but I got this error:
Msg 15253, Level 11, State 1, Procedure sp_rename, Line 105 Syntax
error parsing SQL identifier 'BookPublisher.[[Book_Category]]'.
Can anyone help me?
You do it the same way you do to create it:
exec sp_rename 'BookPublisher."[Book_Category]"', 'Book_Category', 'COLUMN';
Here's a little sample I made to test if this was even possible. At first I just assumed it was a misunderstanding of how [] can be used in SQL Server, turns out I was wrong, it is possible - you have to use double quotes to outside of the brackets.
begin tran
create table [Foo] ("[i]" int);
exec sp_help 'Foo';
exec sp_rename 'Foo."[i]"', 'i', 'column ';
exec sp_help 'Foo';
rollback tran
Double quotes are not required. You simply double up closing square brackets, like so:
EXEC sp_rename 'BookPublisher.[[Book_Category]]]', 'Book_Category', 'COLUMN';
You can find this out yourself using the quotename function:
SELECT QuoteName('[Book_Category]');
-- Result: [[Book_Category]]]
This incidentally works for creating columns, too:
CREATE TABLE dbo.Book (
[[Book_Category]]] int -- "[Book_Category]"
);
this works for me:
exec sp_rename ‘[dbo].[TableName].[OldColumnName]’, ‘NewColumnName’
This worked for me, I was missing the table when renaming the index.
USE database ;
GO
EXEC sp_rename N'Schema.Table.old_INDEX', N'new_INDEX', N'INDEX';
GO
Got that error, and was wondering why. You can get this exact error if the column name you are changing from doesn't exist. Might as well doubly make sure if you still get that error.

Error in SQL stored procedure

I am getting the following error when I execute my stored procedure:
Msg 102, Level 15, State 1, Line 6Incorrect syntax near '2011'.(1 row(s) affected)
Here is the stored procedure:
ALTER PROCEDURE [dbo].[DeliveryFileNames]
AS
BEGIN
SET NOCOUNT ON;
declare #SQL nvarchar(4000)
Create Table #DelivTemp(
Style nvarchar(50),
Material nvarchar(50),
Filename nvarchar(100),
delivered_date date)
set #SQL=
N'insert into #DelivTemp
Select distinct Style,Material,filename
from OPENQUERY(GCS_PRODUCTION,
''SELECT LEFT(FILENAME,locate(''''_'''',FILENAME)-1)as Style,
substring_index(filename,''''_'''',2)as Material,filename,
delivered_date FROM view_delivery_log
where delivered_date > ''2011%'' order by Style '')'
exec (#SQL)
drop table dbo.DelivFN
Select * into dbo.DelivFN
from #DelivTemp
END
I am using OpenQuery to update a SQL table from a linked server on SQL Server 2008 R2.
I know that the underscore is a real issue, but I have tried a plethora of options including \, % and both single and double quotes.
Regardless I am getting the same result. I can run the query independently of the stored procedure and achieve the correct results. The filename field referenced several times is formatted 00000000_ABC4_A.png. I am using the underscore to identify the components of the file name that I need for my reporting purposes.
In addition to the the logical error of your date comparison using the % that the others have pointed out, your current issue is a syntactical error.
Since you've got a dynamic sql statement contained within another dynamic sql statement... you'll need to double-escape all of your single quotes... which you did in most of the query, except for the following line:
where delivered_date > ''2011%'' order by Style '')'
Properly escaped, would be:
where delivered_date > ''''2011%'''' order by Style '')'
Which raises the question... why are you building up the string to execute dynamically, instead of just calling the statement directly?
It's the syntax of ''2011%''. This is not a valid date. % being a wildcard means the compiler can't know what to compare against in the WHERE clause. You'd need to use an actual date: i.e. ''2011_01_01'' so the compiler can know what to compare against
I believe the stored proc exec runs under a different session, therefore you won't have access to the temp table anyway. So, it won't matter if you get that sql statement to run. You could always use YEAR(delivered_date) > 2011.
Another approach would be to use the fqn for the linked server to select into and bypass the temp table all together:
SELECT LEFT(FILENAME,locate('_',FILENAME)-1)as Style,
substring_index(filename,'_',2)as Material,filename,delivered_date
FROM [linked_server_name].[db_name].[dbo].view_delivery_log
into dbo.DelivFN

sql server sp_executesql error with sql string

I have a string that looks like this:
set #sqlstring = N'select #mindate = min(time), #maxdate = max(time) from ' + #st_churn_active_table;
I print it and it looks like this:
select #mindate = min(time), #maxdate = max(time) from derp.derp_table
I run sp_executesql with parameter definitions like this:
execute sp_executesql #sqlstring, N'#maxdate date,#mindate date'
It errors like this:
The parameterized query '(#maxdate date,#mindate date)select #mindate = min(time), #maxda' expects the parameter '#maxdate', which was not supplied.
String becomes
'(#maxdate date,#mindate date)select #mindate = min(time), #maxda'
The sql string is cut off, does anyone know why and how to fix this?
Thanks!
See: How to specify output parameters when you use the sp_executesql stored procedure in SQL Server
First of all, sql server saw the whole string. It's only the error message that truncates it. Notice the error got the name of the missing parameter right, even though the truncated sql string only had part of the name.
Second, this isn't going to work how you want it to. You can't use output parameters that way with sp_executesql.
But finally to the problem of why it's throwing an error. I can't be sure, but I suspect the problem here is that there is a type mismatch, and so it can't use the parameter you gave it. I would hope that sql server would throw a better error message (complain about a type mismatch) in that situation, but I don't have sql server handy to test with and I can't think of any other reason for this to cause a problem.

EXEC(query) AT linkedServer With Oracle DB

I am using Microsoft SQL server 2005. I need to sync data between SQL server and an Oracle db. First thing I need is to find out if the count of data on Oracle side with certain filters(here I use ID as a simple example).
SELECT COUNT(*) FROM oracleServer..owner.table1 WHERE id = #id;
The problem I have is that the table on the lined server or Oracle is very big with 4M rows of data. The above query took about 2minutes to get data back. This code is just a simplied piece. Actually my SP has some other queries to update, insert data from the lined server to my SQL server. The SP took hours or 10+ hours to run with large Oracle db. Therefore T-SQL with lined server is not good for me.
Recently I found OPENQUERY and EXEC (...) AT linedServer. OPENQUERY() is very fast. It took about 0 time to get the same result. However, it does not support variable query or expressions. The query has to be a literal constant string.
EXEC() is in the same way to pass-through query to Oracle. It is fast as well. For example:
EXEC ('SELECT COUNT(*) FROM owner.table1 WHERE id = ' + CAST(#id AS VARCHAR))
AT oracleServer
The problem I have is how to pass the result COUNT(*) back. I tried to google examples in web and msdn. All I can find are SQL or ExpressSQL linedServer examples like:
EXEC ('SELECT ? = COUNT(*) FROM ...', #myCount OUTPUT) AT expressSQL
This query does not work for Oracle. It seems in Oracle, you can set value as output in this way:
SELECT COUNT(*) INTO myCount ...
I tried this:
EXEC ('SELECT COUNT(*) INTO ? FROM ...', #myCount OUTPUT) AT oracleServer
EXEC ('SELECT COUNT(*) INTO : FROM ...', #myCount OUTPUT) AT oracleServer
EXEC ('SELECT : = COUNT(*) FROM ...', #myCount OUTPUT) AT oracleServer
None of those working. I got error message saying query not executable on Oracle server.
I could write a .Net SQL Server project to do the job. Before that, I just wonder if there is anyway way to pass value out as oupput parameter so that I put the better performance T-SQL codes in my SP?
Just a quick update on this. I think I got the solution. I found it in a discussion on a similar issue at Dev NewsGroup. Based on the information, I tried this:
DECLARE #myCount int;
DECLARE #sql nvarchar(max);
set #sql =
N'BEGIN
select count(*) into :myCount from DATAPARC.CTC_MANUAL_DATA;
END;'
EXEC (#sql, #myCount OUTPUT) AT oracleServer;
PRINT #myCount; -- 3393065
Wa! I got the result back in 3 seconds comparing T-SQL query directly on Orable DB (+2minutes). The important thing is to use "BEGIN" and "END;" to wrap the query as anonymous block and don't miss ";" after END
You need anonymous block for output parameters. If you only have input or no parameters, you don't need the block and the query works fine.
Enjoy it! By the way, this is a quick update. If you don't see me again, I would not have any trouble on this issue.
With Linked Services the biggest issue is performance (IMHO)
[linkedserver]...[dbo.RemoteTable] vs OPENQUERY(linkedserver, 'Select * from dbo.RemoteTable') always use the second one
Now to answer the question. OPENQUERY and EXEC() AT is much quicker.
EXEC(Select * from dbo.RemoteTable) AT linkedserver will show the results, but there is no way to re-use.
My simple solution:
SELECT * INTO LocalTable FROM OPENQUERY(linkedserver, 'Select * from dbo.RemoteTable')
OR
INSERT INTO LocalTable SELECT * FROM OPENQUERY(linkedserver, 'Select * from dbo.RemoteTable')
much^10 faster than
SELECT * INTO LocalTable FROM [linkedserver]...[dbo.RemoteTable]