Execute Stored Procedure in a Cursor - sql

I need to execute stored procedure sp_spaceused for all the tables in my database.
I have used cursor for this, please find the below query.The thing is I need to generate report in a single result set.
For the below query I'm getting different results.
Declare #Name Varchar(500)
Declare #GetName Cursor
Set #Getname = Cursor for
select name from sys.tables
Open #Getname
Fetch Next From #Getname into #Name
While ##Fetch_Status=0
Begin
exec sp_spaceused #Name
Fetch Next From #Getname into #Name
End
Close #GetName
Deallocate #GetName

You can use something like the below (the data types may well need tweaking).
Edit: Please see Joe's answer for the correct data types to use!
create table #t
(
name sysname,
rows bigint,
reserved varchar(50),
data varchar(50),
index_size varchar(50),
unused varchar(50)
)
EXEC sp_MSForEachtable 'insert into #t EXEC sp_spaceused ''?'''
select name,rows,reserved,data,index_size,unused
from #t

create table #Temp (
name nvarchar(128),
[rows] char(11),
reserved varchar(18),
data varchar(18),
index_size varchar(18),
unused varchar(18)
)
insert into #Temp
exec sp_msforeachtable 'sp_spaceused [?]'
select * from #Temp

A faster, set-based solution to this problem is to join sys.dm_db_partition_stats and sys.internal_tables, just like sp_spaceused does. The code below is what runs when you generate the "Disk Usage By Table" report in Management Studio.
In my database, the set-based solution returned in 60 ms, while the cursor ran for 22 seconds.
begin try
SELECT
(row_number() over(order by a3.name, a2.name))%2 as l1,
a3.name AS [schemaname],
a2.name AS [tablename],
a1.rows as row_count,
(a1.reserved + ISNULL(a4.reserved,0))* 8 AS reserved,
a1.data * 8 AS data,
(CASE WHEN (a1.used + ISNULL(a4.used,0)) > a1.data THEN (a1.used + ISNULL(a4.used,0)) - a1.data ELSE 0 END) * 8 AS index_size,
(CASE WHEN (a1.reserved + ISNULL(a4.reserved,0)) > a1.used THEN (a1.reserved + ISNULL(a4.reserved,0)) - a1.used ELSE 0 END) * 8 AS unused
FROM
(SELECT
ps.object_id,
SUM (
CASE
WHEN (ps.index_id < 2) THEN row_count
ELSE 0
END
) AS [rows],
SUM (ps.reserved_page_count) AS reserved,
SUM (
CASE
WHEN (ps.index_id < 2) THEN (ps.in_row_data_page_count + ps.lob_used_page_count + ps.row_overflow_used_page_count)
ELSE (ps.lob_used_page_count + ps.row_overflow_used_page_count)
END
) AS data,
SUM (ps.used_page_count) AS used
FROM sys.dm_db_partition_stats ps
GROUP BY ps.object_id) AS a1
LEFT OUTER JOIN
(SELECT
it.parent_id,
SUM(ps.reserved_page_count) AS reserved,
SUM(ps.used_page_count) AS used
FROM sys.dm_db_partition_stats ps
INNER JOIN sys.internal_tables it ON (it.object_id = ps.object_id)
WHERE it.internal_type IN (202,204)
GROUP BY it.parent_id) AS a4 ON (a4.parent_id = a1.object_id)
INNER JOIN sys.all_objects a2 ON ( a1.object_id = a2.object_id )
INNER JOIN sys.schemas a3 ON (a2.schema_id = a3.schema_id)
WHERE a2.type <> N'S' and a2.type <> N'IT'
ORDER BY a3.name, a2.name
end try
begin catch
select
-100 as l1
, 1 as schemaname
, ERROR_NUMBER() as tablename
, ERROR_SEVERITY() as row_count
, ERROR_STATE() as reserved
, ERROR_MESSAGE() as data
, 1 as index_size
, 1 as unused
end catch

Try this:
Create a table (temp or otherwise) that mirrors the result set of the sproc. Then, in the body of your cursor, run this
INSERT INTO <tablename> EXEC sp_spaceused
after you close/deallocate the cursor, select from the table.

Related

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

SQL Loop through tables and columns to find which columns are NOT empty

I created a temp table #test containing 3 fields: ColumnName, TableName, and Id.
I would like to see which rows in the #test table (columns in their respective tables) are not empty? I.e., for every column name that i have in the ColumnName field, and for the corresponding table found in the TableName field, i would like to see whether the column is empty or not. Tried some things (see below) but didn't get anywhere. Help, please.
declare #LoopCounter INT = 1, #maxloopcounter int, #test varchar(100),
#test2 varchar(100), #check int
set #maxloopcounter = (select count(TableName) from #test)
while #LoopCounter <= #maxloopcounter
begin
DECLARE #PropIDs TABLE (tablename varchar(max), id int )
Insert into #PropIDs (tablename, id)
SELECT [tableName], id FROM #test
where id = #LoopCounter
set #test2 = (select columnname from #test where id = #LoopCounter)
declare #sss varchar(max)
set #sss = (select tablename from #PropIDs where id = #LoopCounter)
set #check = (select count(#test2)
from (select tablename
from #PropIDs
where id = #LoopCounter) A
)
print #test2
print #sss
print #check
set #LoopCounter = #LoopCounter + 1
end
In order to use variables as column names and table names in your #Check= query, you will need to use Dynamic SQL.
There is most likely a better way to do this but I cant think of one off hand. Here is what I would do.
Use the select and declare a cursor rather than a while loop as you have it. That way you dont have to count on sequential id's. The cursor would fetch fields columnname, id and tablename
In the loop build a dynamic sql statement
Set #Sql = 'Select Count(*) Cnt Into #Temp2 From ' + TableName + ' Where ' + #columnname + ' Is not null And ' + #columnname <> '''''
Exec(#Sql)
Then check #Temp2 for a value greater than 0 and if this is what you desire you can use the #id that was fetched to update your #Temp table. Putting the result into a scalar variable rather than a temp table would be preferred but cant remember the best way to do that and using a temp table allows you to use an update join so it would well in my opinion.
https://www.mssqltips.com/sqlservertip/1599/sql-server-cursor-example/
http://www.sommarskog.se/dynamic_sql.html
Found a way to extract all non-empty tables from the schema, then just joined with the initial temp table that I had created.
select A.tablename, B.[row_count]
from (select * from #test) A
left join
(SELECT r.table_name, r.row_count, r.[object_id]
FROM sys.tables t
INNER JOIN (
SELECT OBJECT_NAME(s.[object_id]) table_name, SUM(s.row_count) row_count, s.[object_id]
FROM sys.dm_db_partition_stats s
WHERE s.index_id in (0,1)
GROUP BY s.[object_id]
) r on t.[object_id] = r.[object_id]
WHERE r.row_count > 0 ) B
on A.[TableName] = B.[table_name]
WHERE ROW_COUNT > 0
order by b.row_count desc
How about this one - bitmask computed column checks for NULLability. Value in the bitmask tells you if a column is NULL or not. Counting base 2.
CREATE TABLE FindNullComputedMask
(ID int
,val int
,valstr varchar(3)
,NotEmpty as
CASE WHEN ID IS NULL THEN 0 ELSE 1 END
|
CASE WHEN val IS NULL THEN 0 ELSE 2 END
|
CASE WHEN valstr IS NULL THEN 0 ELSE 4 END
)
INSERT FindNullComputedMask
SELECT 1,1,NULL
INSERT FindNullComputedMask
SELECT NULL,2,NULL
INSERT FindNullComputedMask
SELECT 2,NULL, NULL
INSERT FindNullComputedMask
SELECT 3,3,3
SELECT *
FROM FindNullComputedMask

SQL script executes forever - possible loop?

I hope that someone can help me with this script.
I wanted to create an SQL script to rebuild all non clustered index with "online ON" option to prevent locking the tables while rebuilding the indexes, and also without using a cursor (which slow things down). For that reason I used While loop (at least what most SQL developers suggested), so I wrote an SQL script.
What I noticed, SQL script executes forever. On one test machine I left it running for 12 minutes, after which I aborted the operation...
Can some SQL guru please tell me what is causing a bottle neck?
Is there a better way to do this, or perhaps to "fine tune" current script?
Sample of old code:
USE MASTER
GO
DECLARE #DbName AS VARCHAR(50),
#DBIndexName AS VARCHAR(250),
#DBTableName AS VARCHAR(100),
#AlterCommand AS VARCHAR(500),
#SwitchDB AS NVARCHAR(50)
SELECT name INTO #DatabaseList FROM master..sysdatabases
WHILE EXISTS (SELECT * FROM #DatabaseList)
BEGIN
SELECT TOP 1 #DbName = name FROM #DatabaseList
ORDER BY name ASC
SET #SwitchDB = 'USE '+#DbName
EXEC(#SwitchDB)
-- pronaći sve index-e koji imaju fragmentaciju veću od 10%, te staviti u tablicu
SELECT object_name(dt.object_id) Tablename,si.name
IndexName,dt.avg_fragmentation_in_percent AS
ExternalFragmentation,dt.avg_page_space_used_in_percent AS
InternalFragmentation
INTO #FragmIndex
FROM
(
SELECT object_id,index_id,avg_fragmentation_in_percent,avg_page_space_used_in_percent
FROM sys.dm_db_index_physical_stats (db_id(#DbName),null,null,null,'DETAILED')
WHERE index_id <> 0
) AS dt INNER JOIN sys.indexes si ON si.object_id=dt.object_id
AND si.index_id=dt.index_id AND dt.avg_fragmentation_in_percent>10
AND dt.avg_page_space_used_in_percent<75 and si.type_desc = 'NONCLUSTERED' ORDER BY avg_fragmentation_in_percent DESC
-- Napraviti petlju koja će izvršiti rebuild svih indexa
SET #SwitchDB = 'USE master'
EXEC (#SwitchDB)
WHILE EXISTS (SELECT * FROM #FragmIndex)
BEGIN
SELECT TOP 1 #DBIndexName = IndexName, #DBTableName = Tablename FROM #FragmIndex
ORDER BY IndexName ASC
-- rebuild index command setiranje na "ONLINE ON" kako bi se izbjeglo "zaključavanje tablice".
SET #AlterCommand ='ALTER INDEX '+#DBIndexName+' ON '+ #DbName+'.dbo.'+#DbTableName +'REBUILD WITH (FILLFACTOR=80,STATISTICS_NORECOMPUTE = ON,ONLINE=ON)'
EXEC(#AlterCommand)
DELETE #FragmIndex
WHERE IndexName = #DBIndexName
END
DELETE #DatabaseList
WHERE name = #DbName
END
DROP TABLE #DatabaseList
GO
Thank you very much, and best regards.
Just to add new "corrected code" - for all of you that wish to use it, modify it or whatever... :)
USE MASTER
GO
DECLARE #DbName AS VARCHAR(50),
#DBIndexName AS VARCHAR(250),
#DBTableName AS VARCHAR(100),
#AlterCommand AS VARCHAR(500),
#SwitchDB AS NVARCHAR(50),
#numEntries AS BIGINT,
#numIndexEntries AS BIGINT
SELECT name INTO #DatabaseList FROM master..sysdatabases
SET #numEntries = (SELECT COUNT(*) FROM #DatabaseList)
WHILE #numEntries > 0 --EXISTS (SELECT * FROM #DatabaseList)
BEGIN
SELECT TOP 1 #DbName = name FROM #DatabaseList
ORDER BY name ASC
SET #SwitchDB = 'USE '+#DbName
EXEC(#SwitchDB)
-- pronaći sve index-e koji imaju fragmentaciju veću od 10%, te staviti u tablicu
SELECT object_name(dt.object_id) Tablename,si.name
IndexName,dt.avg_fragmentation_in_percent AS
ExternalFragmentation,dt.avg_page_space_used_in_percent AS
InternalFragmentation
INTO #FragmIndex
FROM
(
SELECT object_id,index_id,avg_fragmentation_in_percent,avg_page_space_used_in_percent
FROM sys.dm_db_index_physical_stats (db_id(#DbName),null,null,null,'DETAILED')
WHERE index_id <> 0
) AS dt INNER JOIN sys.indexes si ON si.object_id=dt.object_id
AND si.index_id=dt.index_id AND dt.avg_fragmentation_in_percent>10
AND dt.avg_page_space_used_in_percent<75 and si.type_desc = 'NONCLUSTERED' ORDER BY avg_fragmentation_in_percent DESC
-- Napraviti petlju koja će izvršiti rebuild svih indexa
SET #SwitchDB = 'USE master'
EXEC (#SwitchDB)
SET #numIndexEntries = (SELECT COUNT(*) FROM #FragmIndex)
WHILE #numIndexEntries > 0 --EXISTS (SELECT * FROM #FragmIndex)
BEGIN
SELECT TOP 1 #DBIndexName = IndexName, #DBTableName = Tablename FROM #FragmIndex
ORDER BY IndexName ASC
-- rebuild index command setiranje na "ONLINE ON" kako bi se izbjeglo "zaključavanje tablice".
SET #AlterCommand ='ALTER INDEX '+#DBIndexName+' ON '+ #DbName+'.dbo.'+#DbTableName +'REBUILD WITH (FILLFACTOR=80,STATISTICS_NORECOMPUTE = ON,ONLINE=ON)'
EXEC(#AlterCommand)
DELETE #FragmIndex WHERE IndexName = #DBIndexName
SET #numIndexEntries = (SELECT COUNT(*) FROM #FragmIndex)
END
DELETE #DatabaseList WHERE name = #DbName
SET #numEntries = (SELECT COUNT(*) FROM #DatabaseList)
END
DROP TABLE #DatabaseList
GO
P.S: if you have any other suggestions, or found bug in the script - for improving the code, please let me know.
Two possible problems might cause that effect.
First of all, the DELETE statement may not really delete anything. You can easily check this by PRINTing the number of entries in #DatabaseList after every DELETE statement.
Secondly, the EXISTS (SELECT * FROM #DatabaseList) could just be evaluated once, not upon every iteration of the loop.
I'd change this as follows:
...
DECLARE #numEntries BIGINT
SET #numEntries = (SELECT COUNT(*) FROM #DatabaseList)
WHILE #numEntries > 0
BEGIN
...
DELETE #DatabaseList WHERE name = #DbName
SET #numEntries = (SELECT COUNT(*) FROM #DatabaseList)
END
...

Loop through all the rows of a temp table and call a stored procedure for each row

I have declared a temp table to hold all the required values as follows:
DECLARE #temp TABLE
(
Password INT,
IdTran INT,
Kind VARCHAR(16)
)
INSERT INTO #temp
SELECT s.Password, s.IdTran, 'test'
from signal s inner join vefify v
on s.Password = v.Password
and s.IdTran = v.IdTran
and v.type = 'DEV'
where s.[Type] = 'start'
AND NOT EXISTS (SELECT * FROM signal s2
WHERE s.Password = s2.Password
and s.IdTran = s2.IdTran
and s2.[Type] = 'progress' )
INSERT INTO #temp
SELECT s.Password, s.IdTran, 'test'
FROM signal s inner join vefify v
on s.Password = v.Password
and s.IdTran = v.IdTran
and v.type = 'PROD'
where s.[Type] = 'progress'
AND NOT EXISTS (SELECT * FROM signal s2
WHERE s.Password = s2.Password
and s.IdTran = s2.IdTran
and s2.[Type] = 'finish' )
Now i need to loop through the rows in the #temp table and and for each row call a sp that takes all the parameters of #temp table as input.
How can I achieve this?
you could use a cursor:
DECLARE #id int
DECLARE #pass varchar(100)
DECLARE cur CURSOR FOR SELECT Id, Password FROM #temp
OPEN cur
FETCH NEXT FROM cur INTO #id, #pass
WHILE ##FETCH_STATUS = 0 BEGIN
EXEC mysp #id, #pass ... -- call your sp here
FETCH NEXT FROM cur INTO #id, #pass
END
CLOSE cur
DEALLOCATE cur
Try returning the dataset from your stored procedure to your datatable in C# or VB.Net. Then the large amount of data in your datatable can be copied to your destination table using a Bulk Copy. I have used BulkCopy for loading large datatables with thousands of rows, into Sql tables with great success in terms of performance.
You may want to experiment with BulkCopy in your C# or VB.Net code.
something like this?
DECLARE maxval, val, #ind INT;
SELECT MAX(ID) as maxval FROM table;
while (ind <= maxval ) DO
select `value` as val from `table` where `ID`=ind;
CALL fn(val);
SET ind = ind+1;
end while;
You can do something like this
Declare #min int=0, #max int =0 --Initialize variable here which will be use in loop
Declare #Recordid int,#TO nvarchar(30),#Subject nvarchar(250),#Body nvarchar(max) --Initialize variable here which are useful for your
select ROW_NUMBER() OVER(ORDER BY [Recordid] ) AS Rownumber, Recordid, [To], [Subject], [Body], [Flag]
into #temp_Mail_Mstr FROM Mail_Mstr where Flag='1' --select your condition with row number & get into a temp table
set #min = (select MIN(Rownumber) from #temp_Mail_Mstr); --Get minimum row number from temp table
set #max = (select Max(Rownumber) from #temp_Mail_Mstr); --Get maximum row number from temp table
while(#min <= #max)
BEGIN
select #Recordid=Recordid, #To=[To], #Subject=[Subject], #Body=Body from #temp_Mail_Mstr where Rownumber=#min
-- You can use your variables (like #Recordid,#To,#Subject,#Body) here
-- Do your work here
set #min=#min+1 --Increment of current row number
END
You always don't need a cursor for this. You can do it with a while loop. You should avoid cursors whenever possible. While loop is faster than cursors.

TSQL: Using a Table in a Variable in a Function

I'm trying to do a select from a table that will need to be in a variable. I'm working with tables that are dynamically created from an application. The table will be named CMDB_CI_XXX, where XXX will be an integer value based on a value in another table. The ultimate goal is to get the CI Name from the table.
I've tried passing the pieces that make up the table name to a function and string them together and then return the name value, but I'm not allowed to use an EXEC statement in a function.
This is what I want to execute to get the name value back:
Select [Name] from 'CMDB_CI_' + C.CI_TYPE_ID + Where CI_ID = c.CI_ID
This is the code in the SP that I'd like to use the function in to get the name value:
SELECT
CI_ID,
C.CI_TYPE_ID,
CI_CUSTOM_ID,
STATUS,
CI_TYPE_NAME,
--(Select [Name] from CMDB_CI_ + C.CI_TYPE_ID + Where CI_ID = c.CI_ID)
FROM [footprints].[dbo].[CMDB50_CI_COMMON] c
join [footprints].[dbo].[CMDB50_CI_TYPE] t
on c.CI_TYPE_ID = t.CI_TYPE_ID
where status <> 'retired'
order by CI_TYPE_NAME
I'm not sure what to do with this. Please help?
Thanks,
Jennifer
-- This part would be a SP parameter I expect
DECLARE #tableName varchar(100)
SET #tableName = 'CMDB_CI_508'
-- Main SP code
DECLARE #sqlStm VARCHAR(MAX)
SET #sqlStm = 'SELECT *
FROM '+ #tableName
EXEC (#sqlStm)
Fiddle http://sqlfiddle.com/#!3/436a7/7
First off, yes, I know it's a bad design. I didn't design it. It came with the problem tracking software that my company bought for our call center. So I gave up altogether on the approach I was going for and used a cursor to pull all the the names from the various tables into one temp table and then used said temp table to join to the original query.
ALTER Proc [dbo].[CI_CurrentItems]
As
Declare #CIType nvarchar(6)
Declare #Qry nvarchar(100)
/*
Create Table Temp_CI
( T_CI_ID int,
T_CI_Type_ID int,
T_Name nvarchar(400)
)
*/
Truncate Table Temp_CI
Declare CI_Cursor Cursor For
select distinct CI_TYPE_ID FROM [footprints].[dbo].[CMDB50_CI_COMMON]
where STATUS <> 'Retired'
Open CI_Cursor
Fetch Next from CI_Cursor into #CIType
While ##FETCH_STATUS = 0
BEGIN
Set #Qry = 'Select CI_ID, CI_Type_ID, Name from Footprints.dbo.CMDB50_CI_' + #CIType
Insert into Temp_CI Exec (#Qry)
Fetch Next from CI_Cursor into #CIType
END
Close CI_Cursor
Deallocate CI_Cursor
SELECT CI_ID,
C.CI_TYPE_ID,
CI_CUSTOM_ID,
STATUS,
CI_TYPE_NAME,
T_Name
FROM [footprints].[dbo].[CMDB50_CI_COMMON] c
JOIN [footprints].[dbo].[CMDB50_CI_TYPE] t
ON c.CI_TYPE_ID = t.CI_TYPE_ID
JOIN Temp_CI tc
ON c.CI_ID = tc.T_CI_ID
AND t.CI_TYPE_ID = tc.T_CI_TYPE_ID
WHERE STATUS <> 'retired'
ORDER BY CI_TYPE_NAME