I have a stored procedure called myStoredProcedure in SQL Server 2008 including a code block like this:
...
declare #tempTable table
(
Id int,
Name varchar(100),
Category varchar(50),
Volume int
)
while #startTime<#endTime
begin
insert into #tempTable
EXEC R52_Calculations #param1, #param2, #param3
set #startTime = DATEADD(YEAR,1,#startTime)
end
select * from #tempTable
In this way, the stored procedure is working very well. I can connect to a table to this stored procedure in the SSRS 2008 without any warning or error. However, when I change #tempTable variable into #tempTable like below, I am getting a TimeOut error when I try to connect a table on SSRS 2008 to the updated stored procedure, even though the stored procedure is working very well again in SQL Server.
...
create table #tempTable
(
Id int,
Name varchar(100),
Category varchar(50),
Volume int
)
while #startTime<#endTime
begin
insert into #tempTable
EXEC R52_Calculations #param1, #param2, #param3
set #startTime = DATEADD(YEAR,1,#startTime)
end
select * from #tempTable
This is the error:
Timeout expired. The timeout period elapsed prior to completion of
the operation or the server is not responding. Warning: Null value is
eliminated by an aggregate or other SET operation.
Some more points:
when I remove the "while" loop and do the process only 1 time, there is no error occurring when I use #tempTable.
if I use #temptable (variable one), there is no error occurring at all.
Note that both queries are working fine in SQL Server, the errors are occurring when I try to connect a table on SSRS 2008 to the stored procedure
.
I could not find the reason why #temptable is causing an error. Any clue or help I will appreciate. Thanks.
Related
I have an existing sql server stored procedure, that I'm trying to update. Every time I run Alter Procedure on it, I get the following error:
SQL Error: Must declare the scalar variable "#varOne".
I've Googled around but nothing that I can find helps out with how to get past this error... :/ Procedure below:
ALTER PROCEDURE [dbo].[sp_test] (
-- Declare
#varOne tinyint,
#varTwo numeric(17,0)
) As
Set NoCount On
-- Select
Select *
Into #t
From SQL_Test.dbo.trans with (nolock)
Where test>=123
And Case #varOne When 1 Then rNo When 2 Then iNo When 3 Then sNo End = #varTwo
Union
Select *
From SQL_Test.dbo.trsave with (nolock)
Where date_time > DateAdd(dd, -60, GetDate())
And Case #varOne When 1 Then rNo When 2 Then iNo When 3 Then sNo End = #varTwo
EDIT: I solved the problem by dropping the original procedure, and recreating it. Still curious why the alter would not work. Guessing it is caused by the client using SQL Server 2012.
I solved the problem by dropping the original procedure, and recreating it. Still curious why the alter would not work. Guessing it is caused by the client using SQL Server 2012.
I am trying to insert the data of a stored procedure into a temp table like below
CREATE TABLE #CustomTable3HTML
(
ItemId varchar(30),
ItemId1 varchar(30)
)
INSERT INTO #CustomTable3HTML
EXEC SalesDeals.dbo.prGetDealProposalDetail 17100102, 1
but I am getting this error
Msg 8164, Level 16, State 1, Procedure prGetDealProposalDetail, Line 138 [Batch Start Line 1]
An INSERT EXEC statement cannot be nested.
I figured this is because the stored procedure already has an insert into clause defined and I found out that it can be used only once in the calling chain.
So I started looking for other options and found out about OpenRowSet which I am using as below
SELECT *
INTO #CustomTable3HTML
FROM OPENROWSET('SQLOLEDB','Server=Demo\Demo;Trusted_Connection=Yes;Database=SalesDeals',
'SET NOCOUNT ON;SET FMTONLY OFF;EXEC SalesDeals.dbo.prGetDealProposalDetail 17100102,1')
I am getting an error when I run this SQL command
Access to the remote server is denied because no login-mapping exists.
It works fine when I use a higher level account like sysadmin but fails with the other account which is a normal db owner on the database where I am running this SQL.
There is work around of this. It's not beautiful, but it will work.
In our outer query define a table:
CREATE TABLE #CustomTable3HTML
(
ItemId varchar(30),
ItemId1 varchar(30)
)
Change the procedure adding the following code at the end:
IF OBJECT_ID('tempdb..#CustomTable3HTML')
BEGIN
INSERT INTO #CustomTable3HTML
SELECT ....
END
ELSE
BEGIN
SELECT ....
END
After executing the stored procedure you will have the data in table.
Hi I created a stored procedure that uses OPEN JSON and insert data into a table.
The problem is when I run the stored procedure it shows an error.
I am using SQL server 2016 (SQl Server 13.0.4446.0). I am not getting the same issue when using using sql server 13.0.1742.0
CREATE PROCEDURE [dbo].Test2--'[{"FileId":1,"DataRow":"3000926900"}]'
(
#data varchar(max)
)
AS
BEGIN
create table #Temp
(
FileId bigint,
DataRow nvarchar(max),
DateLoaded DateTime
)
INSERT INTO [dbo].#Temp
SELECT * FROM OPENJSON(#data)
WITH (FileId bigint,
DataRow nvarchar(max),
DateLoaded DateTime)
select * from #temp
END
Error:
If this statement is a common table expression, an xmlnamespaces clause or a change tracking context clause, the previous statement must be terminated with a semicolon.
Check your database compatibility level. OPENJSON is new with SQL Server 2016, and if your compatibility level is set "SQL Server 2014 (120)" or less the OPENJSON function will not be correctly recognized or executed. See the MSDN docs at https://learn.microsoft.com/en-us/sql/t-sql/functions/openjson-transact-sql .
The following SQL script produces an Invalid object name '#temp' exception on SQL Server Profile, but neither SQL Server Management Studio nor sqlcmd raise the exception:
create table #temp (id int)
insert into #temp (id) values (1)
I only caught it by running SQL Server Profiler with the event "Exception" turned on, which can be set on the "Events Selection" tab when configuring the trace properties.
Since exceptions tend to slow down the server, I tried a similar code using a table variable:
declare #temp table (id int)
insert into #temp (id) values (1)
The code above not only avoid the exception, but is also faster when calling it repeatedly, which comproves the performance penalty by using a temporary table:
if (db_id('performance_test') is null)
create database performance_test
go
use performance_test
go
/* --------------------------- */
/* stress test with temp table */
/* --------------------------- */
declare
#i int,
#sql varchar(max),
#start_time datetime,
#end_time datetime
set #i = 0
set #sql = 'create table #temp (id int)' + Char(13) + Char(10) + 'insert into #temp (id) values (1)'
set #start_time = getdate()
while (#i < 10000)
begin
exec (#sql)
set #i = #i + 1
end
set #end_time = getdate()
select [Elapsed milliseconds] = datediff(millisecond, #start_time, #end_time) -- outputs 17090 milliseconds
go
/* ------------------------------- */
/* stress test with table variable */
/* ------------------------------- */
declare
#i int,
#sql varchar(max),
#start_time datetime,
#end_time datetime
set #i = 0
set #sql = 'declare #temp table (id int)' + char(13) + char(10) + 'insert into #temp (id) values (1)'
set #start_time = getdate()
while (#i < 10000)
begin
exec (#sql)
set #i = #i + 1
end
set #end_time = getdate()
select [Elapsed milliseconds] = datediff(millisecond, #start_time, #end_time) -- outputs 10010 milliseconds
I often read that a local temporary table and a table variable can be used interchangeably (if using a single batch, of course), however I think the demonstrated behavior above can prove otherwise.
Although it's kinda obvious, it's worth noting that the exception is not raised if we separate the create table from insert into in different batches:
create table #temp (id int)
go
insert into #temp (id) values (1)
Is this silent exception a SQL Server's bug or is it something that could be called "a feature by design"? Maybe it's simply better to always use table variables instead of temporary tables, given the silent exception above.
P.S.: I've tested on both SQL Server 2014 and SQL Server 2016 Developer editions, getting the same results.
As pointed out by #JeroenMostert, the exception "Invalid object name" is probably resolved in the batch recompilation (which I didn't know about). It makes perfect sense considering the "Deferred name Resolution" process, which is a known subject in the SQL Server community.
The first link below is a question I've posted on MSDN and was answered by Mohsin_A_Khan, talking about "Deferred name Resolution" process in SQL Server. The other two links contributes to understand how it actually works:
Getting "Invalid object name" by creating a temp table and inserting rows right away
How to find what caused errors reported in a SQL Server profiler trace?
Deferred Name Resolution and Compilation
Since the "Invalid object name" is expected due to the recompilation process and shouldn't be avoided by simply replacing the temporary table with a table variable (again, as pointed out by #JeroenMostert), I consider this question answered.
I'm executing stored procedures using SET FMTONLY ON, in order to emulate what our code generator does. However, it seems that the results are cached when executed like this, as I'm still getting a Conversion failed error from a proc that I have just dropped! This happens even when I execute the proc without SET FMTONLY ON.
Can anyone please tell me what's going on here?
Some statements will still be executed, even with SET FMTONLY ON. You "Conversion failed" error could be from something as simple as a set variable statement in the stored proc. For example, this returns the metadata for the first query, but throws an exception when it runs the last statement:
SET FMTONLY on
select 1 as a
declare #a int
set #a = 'a'
As for running a dropped procedure, that's a new one to me. SQL Server uses the system tables to determine the object to execute, so it doesn't matter if the execution plan is cached for that object. If you drop it, it is deleted from the system tables, and should never be executable. Could you please query sysobjects (or sys.objects) just before you execute the procedure? I expect you'll find that you haven't dropped it.
This sounds like a client-side error. Do you get the same message when running through SQL Management Studio?
Have you confirmed that there isn't another procedure with the same name that's owned by a different schema/user?
DDL statements are parsed, but ignored when run if SET FMTONLY ON has been executed on the connection. So if you drop a proc, table, etc when FMTONLY is ON, the statement is parsed, but the action is not executed.
Try this to verify
SET FMTONLY OFF
--Create table to test on
CREATE TABLE TestTable (Column1 INT, Column2 INT)
--insert 1 record
INSERT INTO TestTable (Column1, Column2)
VALUES (1,2)
--validate the record was inserted
SELECT * FROM TestTable
--now set format only to ON
SET FMTONLY ON
--columns are returned, but no data
SELECT * FROM TestTable
--perform DDL statement with FMTONLY ON
DROP TABLE TestTable
--Turn FMTONLY OFF again
SET FMTONLY OFF
--The table was dropped above, so this should not work
SELECT * FROM TestTable
DROP TABLE TestTable
SELECT * FROM TestTable