error in sql query result - sql

I have this query
DECLARE #Base nvarchar(200)
SET #Base = 'WITH Base AS (SELECT Id, ROW_NUMBER() OVER (ORDER BY Id DESC) RN FROM'
+ Quotename(#SampleWorkTbl) + ')
SELECT * INTO ##temp FROM Base'
EXEC (#Base)
SELECT * FROM ##temp
declare #command nvarchar(max)
Set #command='SELECT TOP 15 [Name],[ImageAddress],(SELECT TOP 1 COUNT(Id) FROM' + QUOTENAME(#SampleWorkTbl) + ') as AllSampleCount FROM ' + QUOTENAME(#SampleWorkTbl) +
' WHERE [Id] IN (SELECT TOP 15 Id From ##temp WHERE RN > ((#Count-1)*15) ORDER BY Id DESC) ORDER BY Id DESC'
exec (#command)
drop table ##temp
I want get [Name],[ImageAddress] and count of Id from any table name that pass to the procedure
but instead of get name , image address and Id I get this data
Id RN
10 1
9 2
8 3
7 4
6 5
5 6
4 7
3 8
2 9
1 10
and when try again i get this error
There is already an object named '##temp' in the database.
#SampleWorkTbl is a name of any table that pass to the this query
how i can fix this problem ?
thank you for you help

Your Query is executing until
EXEC (#Base)
You are getting the
There is already an object named '##temp' in the database.
at
SELECT * FROM ##temp
means you got error somewhere and it didn't reached the point
drop table ##temp
as #Ganesh_Devlekar mentioned
Try adding
if (object_ID('tempdb..##temp')) is not NULL
DROP TABLE ##temp
at the Starting

try this:
For
There is already an object named '##temp' in the database.
Before Creating New Temp Table You need to Use This:
if (object_ID('tempdb..##temp')) is not NULL
DROP TABLE ##temp
You need to add [Name],[ImageAddress],ID these columns to get desire output
SET #Base = 'WITH Base AS (SELECT [Name],[ImageAddress],ID,COUNT(ID) CntID, ROW_NUMBER() OVER (ORDER BY Id DESC) RN FROM'
+ Quotename(#SampleWorkTbl) + ' GROUP BY [Name],[ImageAddress],ID)
SELECT * INTO ##temp FROM Base'

Related

How to get Output parameter from a column in table for a stored procedure

I've stored procedure like this:
create procedure sp_testsp
(
#vc_order_by varchar(100),
#int_start_index INT,
#int_grid_size INT,
#count bigint output
)
as
begin
select * from
(select ROW_NUMBER() over
(order by
case #vc_order_by = '' then tab1.int_id end desc) AS row,
*,
COUNT(tab1.int_id) OVER() as totalRowCount
from
(select * from tbl_test) tab1) tab2
where row BETWEEN CONVERT(VARCHAR, #int_start_index) and CONVERT(VARCHAR,(#int_start_index-1) + #int_grid_size);
set #count = 0;
end
We can execute the above stored procedure by:
DECLARE #size bigint;
EXEC sp_testsp '', 1,5, #size output;
SELECT #size;
The written sp provides data based on pagination and we can retrieve 100 or any number of records by passing a number in #int_grid_size .
The table output looks like following:
row int_id vc_name totalRowCount
1 5 a 107
2 6 ab 107
3 7 abc 107
4 8 abcd 107
5 10 abcc 107
The last column gives the total records count of the table or total record if we use where condition.
I want to OUTPUT any one column value of the totalRowCount in '#count' in the stored procedure.
I cannot use ##ROWCOUNT as it only sends the count of records the sp is outputting i.e in this case 5 but actual records are 107.
Just wondering if there is any way. Any help is apperciated. Thanks.
Edit:
I tried something like this, and it works:
create procedure sp_testsp
#param1 nvarchar(800),
#count bigint output
as
begin
select * from tbl_test tt where tt.col1 = #param1;
set #count = select Count(*) from tbl_test tt where tt.col1 = #param1;
end
The issue with this is I've to call the query once and then call the query again for #count. This is working but taking lot of time for big queries.
You can do that by temp table
select * into #temp from
(select ROW_NUMBER() over
(order by
case #vc_order_by = '' then tab1.int_id end desc) AS row,
*,
COUNT(tab1.int_id) OVER() as totalRowCount
from
(select * from tbl_test) tab1) tab2
where row BETWEEN CONVERT(VARCHAR, #int_start_index) and CONVERT(VARCHAR,(#int_start_index-1) + #int_grid_size);
select top 1 #count=totalRowCount from #temp
select * from #temp --you can exclude totalRowCount

How to create stored procedure with view?

I tried to execute this code and it worked o.k without the the stored procedure and with it, it made an error.
The error is:
Msg 102, Level 15, State 1, Procedure UV_MTBF, Line 251
Incorrect syntax near 'Event_'.
Is the stored procedure have a limitation in length?
can someone help me with my code?
edit*
my problem is with ' + QUOTENAME(#category,N'''') + N'
i want to add an integer from a variable that i received in the stored procedure. how can i do it?
enter code here:
CREATE PROCEDURE dbo.MTBFCalculation #Category int, #Action bit, #relateToParent bit
as
IF EXISTS (SELECT 1 FROM sys.objects WHERE [name] = '[dbo].[UV_MTBF]')
DROP VIEW [dbo].[UV_MTBF];
DECLARE #Event nvarchar(MAX) = N'
CREATE VIEW [dbo].[UV_MTBF]
as
with failureReportTable as (SELECT [ID] as failure_id
,[Login_ID]
,[Event_ID]
,[StartDate]
,[EndDate]
,DATEDIFF(Hour,[StartDate],[EndDate]) as eventDurationMin
,[IsRelevantForBI]
,[IsParallelReport]
,[ParentReportID]
,[IsPausedEvent]
,Case
When ParentReportID>0 Then 1 --Chiled
When IsParallelReport=1 Then 2 --Parent
Else 3 --not Parallel
End as ParallelStatus
FROM [TDM_Analysis].[dbo].[FailureReports]),
fullFailure as (select *, ROW_NUMBER() OVER (ORDER BY [StartDate] ) AS IDrow
from failureReportTable join [TDM_Analysis].[dbo].[UV_filteredLogins] as viewLogins on failureReportTable.Login_ID=viewLogins.ID
WHERE event_id IN (SELECT ID FROM [TDM_Analysis].[dbo].[Events] where EventCategory_ID=' + QUOTENAME(#category,N'''') + N')
and (ParallelStatus=3 or ParallelStatus=(case when ' + QUOTENAME(#relateToParent,N'''') + N'=1 then 2 else 1 end))),
--------------create first failure table------------------
failure_Event_1 as (select f1.failure_id as Event_1_Failure_ID
,f1.[Login_ID] as Event_1_Login_ID
,f1.[Event_ID] as Event_1_Event_ID
,f1.[StartDate] as Event_1_StartDate
,f1.[EndDate] as Event_1_EndDate
,f1.eventDurationMin as Event_1_eventDurationMin
--,f1.[IsRelevantForBI] as Event_1_IsRelevantForBI
--,f1.[IsParallelReport] as Event_1_IsParallelReport
-- ,f1.[ParentReportID] as Event_1_ParentReportID
-- ,f1.[IsPausedEvent] as Event_1_IsPausedEvent
,f1.[Test_Name] as Event_1_TestName
,f1.Phase_Name as Event_1_PhaseName
,f1.PressName as Event_1_PressName
,f1.PressType as Event_1_PressType
--,f1.[Operator] as Event_1_Operator
,f1.[LoginDate] as Event_1_LoginDate
,f1.[LogoutDate] as Event_1_LogoutDate
,f1.TimeDiff as Event_1_LoginDuration
,f1.IDrow+1 as row1
from fullFailure as f1),
--------------create second failure table------------------
failure_Event_2 as (select f1.failure_id as Event_2_Failure_ID
,f1.[Login_ID] as Event_2_Login_ID
,f1.[Event_ID] as Event_2_Event_ID
,f1.[StartDate] as Event_2_StartDate
,f1.[EndDate] as Event_2_EndDate
,f1.eventDurationMin as Event_2_eventDurationMin
-- ,f1.[IsRelevantForBI] as Event_2_IsRelevantForBI
-- ,f1.[IsParallelReport] as Event_2_IsParallelReport
-- ,f1.[ParentReportID] as Event_2_ParentReportID
-- ,f1.[IsPausedEvent] as Event_2_IsPausedEvent
,f1.[Test_Name] as Event_2_TestName
,f1.Phase_Name as Event_2_PhaseName
,f1.PressName as Event_2_PressName
,f1.PressType as Event_2_PressType
-- ,f1.[Operator] as Event_2_Operator
,f1.[LoginDate] as Event_2_LoginDate
,f1.[LogoutDate] as Event_2_LogoutDate
,f1.TimeDiff as Event_2_LoginDuration
,f1.IDrow as row2
from fullFailure as f1),
------------- join two failure tabels and calculating MTTR-mean time to repair (duration of failue), MTTF-mean time to failue( end of one until start of a new one), MTBF-mean time between failue (from start of a failure to start of a new one)--------------------
joinFailures as (select *, Event_1_eventDurationMin as MTTR
,CASE
When isnull(f2.row2,0)=0 then DATEDIFF(HOUR,f1.Event_1_EndDate,f1.Event_1_LogoutDate)
WHEN f1.Event_1_Login_ID=f2.Event_2_Login_ID THEN DATEDIFF(HOUR,f1.Event_1_EndDate,f2.Event_2_StartDate)
When (select TOP 1 sum(timediff)
from [TDM_Analysis].[dbo].[UV_filteredLogins]
where logindate>f1.Event_1_LogoutDate and logindate<f2.Event_2_LoginDate) is null then DATEDIFF(HOUR,f1.Event_1_EndDate,f1.Event_1_LogoutDate)+DATEDIFF(HOUR,f2.Event_2_LoginDate, f2.Event_2_StartDate)
ELSE
(select TOP 1 sum(timediff)+DATEDIFF(HOUR,f1.Event_1_EndDate,f1.Event_1_LogoutDate)+DATEDIFF(HOUR,f2.Event_2_LoginDate, f2.Event_2_StartDate)
from [TDM_Analysis].[dbo].[UV_filteredLogins]
where logindate>f1.Event_1_LogoutDate and logindate<f2.Event_2_LoginDate)
END AS MTTF
from failure_Event_1 as f1 left join failure_Event_2 as f2 on f1.row1=f2.row2),
positiveJoinFailure as (select * from joinFailures where MTTF>=0)
---- select calculation table order by ascending time----------
select * --Event_1_Failure_ID,Event_2_Failure_ID,MTTR,MTTF, MTTR+MTTF as MTFB
from positiveJoinFailure
--order by row1
';
--------------------------------------------------------Action------------------------------------------------------------------------------
if #Action=1
begin
EXEC sp_executesql #Event;
end
for this part of your query
where EventCategory_ID=' + QUOTENAME(#category,N'''') + N')
2 option here, you convert the value of #category to string and then concatenate with the dynamic query
where EventCategory_ID=' + convert(varchar(10), #category)
OR, you pass the value in as a parameter.
for this option, you specify #category in the dynamic query
where EventCategory_ID= #category
and (ParallelStatus=3 ....
and you pass the value in at sp_executesql
EXEC sp_executesql #Event, N'#category int', #category
By the way, Option 2 is the preferred method when using dynamic query

Dynamic SQL - union all tables (number of tables is dynamically created)

I don't know how to union all tables with dynamic SQL.
The issue is that I'm inserting into db a number of tables - all having the same structure (only one varchar column
[Line]
). I don't know that would be the number of tables inserted - it depends on the project. But I want to automate the process in SQL.
I'm using this query to find those tables, additionally I'm adding some [RowNum] that may serve as an ID of each table:
SELECT
ROW_NUMBER() OVER (ORDER BY Name) AS [RowNum],
[Name] AS [Name]
INTO #all_tables_with_ids
FROM #all_tables
This query returns:
RowNum | Name
------------------------
1 | Table 1
2 | Table 2
3 | Table 3
4 | Table 4
I would like to merge all tables together. I was trying to write some insert into in while loop but it didn't work. I figured out that I need dynamic SQL.
Can you suggest something? I was trying to find some examples but all of them fail due to the fact that the list of tables is not known at the beginning, so it needs to be created dynamically as well.
Demo here:
create table #test
(
RowNum int,
Name varchar(100)
)
insert into #test
select 1,quotename('table1')
union all
select 2,quotename('table2')
declare #sql nvarchar(max)
set #sql='select somecol from tbl union all '
declare #sql1 nvarchar(max)
;with cte
as
(select #sql as ql,name,rplc
from
#test t1
cross apply
(select replace(#sql,'tbl',name) as rplc from #test t2 where t1.rownum=t2.rownum)b
)
select #sql1= stuff(
(select ''+rplc
from cte
for xml path('')
),1,0,'')
set #sql1=substring(#sql1,1,len(#sql1)-10)
print #sql1
--exec(#Sql1)

Create a Table based on a list from another table

I have compiled a list of columns which I hope to build a table with. Is it possible to use a procedure to create a table based on this list? Ie
List
A
B
C
New_Table
Column A Column B Column C
Customer is atable consist of column List with rows:- A, B, C
What I've done is added a RowNum column on run time into the customer table which is dynamic. Due to this another column of row number got attached with List column. Using this:-
RowNum=1 provides A
RowNum=2 provides B
RowNum=3 provides C
Here is the procedure as per your requirement. Please verify:-
create procedure newtable
#tablename NVARCHAR(1000)
as
Declare #col1 varchar(50),#col2 varchar(50),#col3 varchar(50), #cmd NVARCHAR(1000)
select #col1=List from (select List,ROW_NUMBER() Over(Order by List) as RowNum from customer)x where x.RowNum=1
select #col2=List from (select List,ROW_NUMBER() Over(Order by List) as RowNum from customer)x where x.RowNum=2
select #col3=List from (select List,ROW_NUMBER() Over(Order by List) as RowNum from customer)x where x.RowNum=3
set #cmd=N'Create Table '+#tablename+ N' (' + #col1+N' Varchar(50),'+#col2 + N' varchar(50),'+#col3+N' varchar(50))' ;
print #cmd
Exec(#cmd)
After this run your command:-
exec newtable 'New_table'

Explicit command work, while its TSQL equivalent throws an error

Error:
Could not find stored procedure 'SELECT TOP 1 name FROM (SELECT TOP 5 name FROM sys.tables ORDER BY name DESC) as t ORDER BY name ASC'.
Code:
WHILE (#interval <= #max)
BEGIN
SET #SQL = 'SELECT TOP 1 name FROM (' +
SELECT TOP ' + convert(varchar(10), #interval) +
' name FROM sys.tables ORDER BY name DESC) as t ORDER BY name ASC'
EXEC #SQL
SELECT #interval = #interval + 1
END
Executing the following command on its own works properly:
SELECT TOP 1 name
FROM
(SELECT TOP 5 name
FROM sys.tables
ORDER BY name DESC) as t
ORDER BY
name ASC
Incrementing the inner TOP # manually and running the command without TSQL will rotate through each table properly. (This will eventually include a nested loop for Column, and another nested loop for a search within that column.)
That the command runs without the variable makes me think this is a scope issue. Shouldn't I be able to resolve this by inserting the list of table names into a temp table with a Primary Key of Seed 1, Increment 1 for a row_id, and then looping through the table via incrementing my #row_id = row_id?
Any suggestions?
It should be exec(#sql), I think