OPENQUERY throws error when used with WIN2K8\SQL2K12 - sql-server-2012

I'm trying the following Sql query to move my stored procedure result into table
SELECT *
INTO #tmpTable
FROM OPENQUERY(WIN2K8\SQL2K12, 'EXEC vcs_gauge #gauge_name=vs1_bag,#first_rec_time=2014-09-01 09:00:00,#last_rec_time=2014-09-01 10:00:00')
following error is thrown, when I execute the query.
Incorrect syntax near '\'.
I don't want to add linked server .How to resolve this issue?
EDIT1
When I do [win2k8\sql2k12], and first execute the following command
EXEC sp_serveroption 'YourServer', 'DATA ACCESS', TRUE
A new message comes
OLE DB provider "SQLNCLI11" for linked server "WIN2K8\SQL2K12" returned message "Deferred prepare could not be completed.".
Msg 8180, Level 16, State 1, Line 1
Statement(s) could not be prepared.
Msg 102, Level 15, State 1, Line 1
Incorrect syntax near '-'.

You need to enclose DATETIME values in single quotes. And since your query is in a string itself, those single-quotes need to be doubled / escaped as follows (and you should probably also put the first parameter's value in escaped-single-quotes as it is clearly a string).
You should also fully qualify the stored procedure name with [DatabaseName].[SchemaName]..
And since the vcs_gauge proc uses Dynamic SQL, you need to specify the WITH RESULT SETS clause. For more info on this clause, please see the MSDN page for EXECUTE.
SELECT *
INTO #tmpTable
FROM OPENQUERY([WIN2K8\SQL2K12],
N'EXEC [DatabaseName].[SchemaName].vcs_gauge
#gauge_name = ''vs1_bag'',
#first_rec_time = ''2014-09-01 09:00:00'',
#last_rec_time = ''2014-09-01 10:00:00''
WITH RESULT SETS ( { column_specification} );
');

Related

sp_refreshsqlmodule is failing with UNION, INTERSECT or EXCEPT operator must have an equal number of expressions error

I have written one stored procedure where I have added UNION like this:
SELECT *,SysStartTime, SysEndTime FROM dbo.FirstTable WHERE Id = #Id
UNION
SELECT * FROM history.FirstTable WHERE Id = #Id
where dbo.FirstTable is temporal table and history.FirstTable is it's history table.
If I write a query like:
exec sp_refreshsqlmodule N'USP_MySPName'
It fails with below error:
Msg 205, Level 16, State 1, Procedure sys.sp_refreshsqlmodule_internal, Line 85 [Batch Start Line 0]
All queries combined using a UNION, INTERSECT or EXCEPT operator must have an equal number of expressions in their target lists.
However if I alter it, it doesn't show any error. And even while execution it doesn't show any error. Even if I execute the above query separately it works fine.
I tried searching for the cause of this error but I m not able to find any reference.
Can someone help me with the reason for this error.
NOTE: This error can be fixed with manually specifying all the column names from both tables instead if using *

Trying to add a column to SQL Server table

I am getting incorrect syntax errors with the following statement (SQL Server 2017)
USE ToDo
GO
ALTER TABLE tasks ADD COLUMN completed TINYINT(1);
Started executing query at Line 1
Commands completed successfully.
20:31:38Started executing query at Line 3
Msg 156, Level 15, State 1, Line 3
Incorrect syntax near the keyword 'COLUMN'.
A very similar syntax was used to remove a column that worked fine.
This code would run in MySQL - but not on SQL Server. Consider:
alter table tasks add completed tinyint;
Rationale:
alter table does not support column in SQL Server; just remove that keyword
the tinyint datatype does not take a length

Why won't this Azure SQL Stored Procedure execute?

I can't figure out why this won't execute.
Created the SP with:
CREATE PROCEDURE [dbo].[sp_custom_addADUser]
#userNameParam NVARCHAR(255)
AS
CREATE USER [#userNameParam]
FROM EXTERNAL PROVIDER
WITH DEFAULT_SCHEMA = dbo;
ALTER ROLE testRole ADD MEMBER [#userNameParam]
I have GRANT EXECUTE ON dbo.sp_custom_addADUser permissions:
|role_name| user_name |
|---------|--------------------|
|testRole |myname#mycompany.com|
|name |ObjectType |PermissionType |permission_name|state_desc|ObjectType|SchemaName|ObjectName|
|--------|-------------|----------------|---------------|----------|----------|----------|----------|
|testRole|DATABASE_ROLE|OBJECT_OR_COLUMN|EXECUTE|GRANT|SQL_STORED_PROCEDURE|dbo|sp_custom_addADUser|
From SSMS, execute the SP by passing it the string: someone#mycompany.com (actual user).
Error is:
Msg 15007, Level 16, State 6, Procedure dbo.sp_custom_addADUser, Line 12 [Batch Start Line 0]
'#userNameParam' is not a valid login or you do not have permission.
Msg 15151, Level 16, State 1, Procedure dbo.sp_custom_addADUser, Line 16 [Batch Start Line 0]
Cannot add the principal '#userNameParam', because it does not exist or you do not have permission.
(1 row affected)
The error message gives a hint of what's happening -- it's using the parameter name #userNameParam where you would want it to be using the value someone#mycompany.com.
This is because CREATE USER can't accept a parameter (as this previous answer mentions).
One option is to use dynamic SQL. I.e., build the SQL statement you want to execute as a string -- concatenating in the value of the parameter -- and then run it with sp_executesql.
Make sure you understand the risks of SQL Injection and how to mitigate them before using dynamic SQL.
It's reading [#userNameParam] as a quoted identifier (like a column name), not as a variable, because of the square brackets. However, you can't use a variable for an object name, like a user name for instance, so just removing the brackets won't get the job done. You'll need a touch of dynamic SQL to make it all happen.
With any dynamic SQL, you'll want to include measures to avoid SQL injection, so I used both a parameterized query and QUOTENAME for the example code. The #CRLF variable just injects carriage return/line feeds into the dynamic string for readability when you print the result for debugging. There are multiple lines in the string builder for readability when looking at the procedure code.
See the excellent link in Tim Goodman's answer for more details here.
CREATE PROCEDURE [dbo].[sp_custom_addADUser]
#userNameParam NVARCHAR(255)
AS
DECLARE #sqlCreate NVARCHAR(500)
,#sqlAlter NVARCHAR(500)
,#CRLF CHAR(2) = CHAR(10)+CHAR(13);
SET #sqlCreate = CONCAT(#sqlCreate, 'CREATE USER #userName', #CRLF);
SET #sqlCreate = CONCAT(#sqlCreate, 'FROM EXTERNAL PROVIDER', #CRLF);
SET #sqlCreate = CONCAT(#sqlCreate, 'WITH DEFAULT_SCHEMA = dbo;');
--PRINT #sqlCreate;
EXECUTE sp_executesql #sqlCreate, N'#userName', QUOTENAME(#userNameParam);
SET #sqlAlter = ('ALTER ROLE testRole ADD MEMBER #userName;');
--PRINT #sqlAlter;
EXECUTE sp_executesql #sqlAlter, N'#userName', QUOTENAME(#userNameParam);

Table structure using sp_help

When I tried this query:
sp_help '[OG_System].[dbo].[tbl_act]'
This message appears:
Msg 15250, Level 16, State 1, Procedure sp_help, Line 48
The database name component of the object qualifier must be the name of the current database.
Because your target database is different than current database.
Use;
EXEC [ServerName].[DatabaseName].dbo.sp_help 'tbl_act'
thanks goGud, I know the correct usage of sp_columns.
EXEC [ServerName].[DatabaseName].dbo.sp_columns 'tbl_act'

Msg 8152, Level 16, State 14, Line XXX String or binary data would be truncate

Scenario: A large stored procedure is run thousands of time a day, 6 days a weeks every year. For this one specific situation I'm getting an error
Msg 8152, Level 16, State 14, Line 114
String or binary data would be truncated
This stored procedure is about 800 lines of code, with lots of parameters, lots of variables and lots of tables.
Go
#exampleParam varchar(30)
#exampleParam datetime
DECLARE #declaredvara VARCHAR(50);
DECLARE #declaredvarb VARCHAR(50); -- where the line error is according to the printout
DECLARE #declaredvarc VARCHAR(50);
DECLARE #declaredvard VARCHAR(50); -- where line error is adjusted for comments in front of GO
BEGIN TRANS
-- some calculations (700+ lines)
COMMIT TRANS
--error catch
ROLLBACK TRANS
Problem: I'm want to know if its possible to get an accurate Line error read, so I can at least narrow down which tables I have to check. There are tons of tables involved in this stored procedure.
*** Both declared variables(before and after adjustment of GO) it points to are dead weight, they're nvr used.
Bonus info: I ran the stored procedure with params populated and params = '' except for the datetimes. In both cases I got the same error. However, I know the stored procedure works because it's being used thousands of times a day w/out this error.
EXEC SP '','','','','2014-11-6'
EXEC SP 'XX_XX_XX','',1,'','2014-11-6'
--both return the same error of Msg 8152, Level 16, State 14
--XX is a specific serialnum.
--However all other serialnum have no problem
EDIT: The DB is running SQL Server 2005
EDIT2: I'm using SQL Server 2008 to edit. - So debug isn't an option
Used that it will fix Msg 8152, Level 16, State 14, Line 114
String or binary data would be truncated.
SET ansi_warnings OFF
GO
BEGIN CATCH
DECLARE #body VARCHAR(4000)
SET #body='<b>Exception in spname </b><br/>'
SET #body=#body + ( SELECT
'<b>Error No :</b> '+ CONVERT(VARCHAR(100),ERROR_NUMBER()) +'<br/>'
+'<b>Error Severity :</b> '+CONVERT(VARCHAR(1000),ERROR_SEVERITY()) +'<br/>'
+'<b>Error State :</b> '+CONVERT(VARCHAR(1000),ERROR_STATE()) + '<br/>'
+'<b>Error Procedure :</b> '+CONVERT(VARCHAR(1000),ERROR_PROCEDURE())+'<br/>'
+'<b>Error Line :</b> '+CONVERT(VARCHAR(100),ERROR_LINE())+'<br/>'
+'<b>Error Message :</b> '+CONVERT(VARCHAR(2000),ERROR_MESSAGE()));
END CATCH
This error indicates that you are going to store some thing bigger that it's storage. you may need to check if you are going to store some string with more that 50 characters in #declaredvara or #declaredvarb or #declaredvarc or #declaredvard or any other variables or table columns. for example you may define #test as varchar(2) and then try to insert 'vahid' into it. in this case similar exception will be thrown. There is 2 way(as I know) that you can find the error ocurance line:
If you need to find the exact line of error occurrence you may need to debug you SP using sql server debug tools(Read more about debugging in Sql Server here)
You can also use TRY...CATCH blocks to check which block of code in you SP causes the error.
It turns out one of the variables in the area was declared but never given a value.
That variable was later used as a param in executing another stored procedure from within.
Which resulted in a null param being passed into a param that couldn't contain it.
Thanks everyone for the responses.
if your inserting in varchar(3) and selecting from varchar(10), you are getting the error. You have to design them same as varchar(3) or varchar(10).