I have this select's result
I'm trying to use this code, but I don't have an int id.
DECLARE #LoopCounter INT = 1, #MaxLAB INT ,
lib NVARCHAR(100)
set #MaxLAB=(select count(LAB_UM) from STARE_LAB_DEMANDE )
WHILE(#LoopCounter <= #MaxLAB)
BEGIN
SELECT lib = LAB_UM
FROM Mytable WHERE Id = #LoopCounter
PRINT lib
SET #LoopCounter = #LoopCounter + 1
END
I want to loop over this records. The id is lab_um.
You can loop through in LAB_UM order easily enough:
declare #lib varchar(50)
set #lib=''
while exists(select * from table where lab_um>#lib)
begin
set #lib=(select min(lab_um) from table where lab_um>#lib)
/*do stuff here */
end
Related
My problem is this; I have a field in a table that contains values like this:
NP
NP;MC;PE
MC;AB;AT;MI;TC;WM
OS
OG
I want to convert these abbreviations to their full name. i.e. NP becomes Nuclear Power, OG becomes Oil and Gas, MI becomes Military etc.
My desired output would be:
Nuclear Power
Nuclear Power;Military;Pesticides
and so on.
I'm creating this as a function. I got it working for just the one abbreviation and then the same for two. However my issue is that I may have 5 abbreviations or 7. I know my current approach is dreadful but cannot figure out how to loop it in the right way.
Please note: I've shortened the list of abbreviations for StackOverflow but there's 25 in total.
Please further note: I did the function bottom up (I don't know why) and got the two value and single value working. I've removed anything I did for values over 3 as nothing I did worked.
ALTER FUNCTION [dbo].[get_str_full]
(
-- Add the parameters for the function here
#str_input VARCHAR(250)
)
RETURNS VARCHAR(250)
AS
BEGIN
-- Declare the return variable here
DECLARE #Result VARCHAR(250)
DECLARE #TEMPSTRING VARCHAR(250)
DECLARE #TEMPSTRING_RIGHT AS VARCHAR(250)
-- DECLARE #PI_COUNT BIGINT
DECLARE #COUNTER INT
DECLARE #TOTAL_VALS BIGINT
DECLARE #STRING_ST VARCHAR(250)
DECLARE #POS_STR BIGINT
DECLARE #REMAINING_STR VARCHAR(250)
-- Used for easy loop skips
DECLARE #LEFTSKIP AS BIGINT
SET #LEFTSKIP = 1
SET #Result = #str_input
SET #STRING_ST = #Result
SET #COUNTER = (LEN(#Result) - LEN(REPLACE(#Result,';',''))) + 1
SET #TOTAL_VALS = (LEN(#Result) - LEN(REPLACE(#Result,';',''))) + 1
-- If the string has a semicolon then there's more than one PI value
IF CHARINDEX(';', #Result) > 0
BEGIN
WHILE #COUNTER > 0
BEGIN
IF #TOTAL_VALS >= 3 -- If counter is more than 2 then there's three or more
BEGIN
DECLARE #TEMP_VAL BIGINT
SET #TEMP_VAL = 5
END
ELSE IF #TOTAL_VALS = 2-- Theres 2
BEGIN
-- Do left two chars first
IF #LEFTSKIP = 1
BEGIN
SET #TEMPSTRING = LEFT(#Result, 2)
SELECT #TEMPSTRING = CASE #TEMPSTRING
WHEN 'MC' THEN 'Military Contracting'
WHEN 'NP' THEN 'Nuclear'
WHEN 'OG' THEN 'Oil & Gas'
WHEN 'OS' THEN 'Oil Sands'
WHEN 'PM' THEN 'Palm Oil'
WHEN 'PE' THEN 'Pesticides'
ELSE #TEMPSTRING
END
SET #LEFTSKIP = 2
END
ELSE IF #LEFTSKIP = 2
BEGIN
SET #TEMPSTRING_RIGHT = RIGHT(#Result, 2)
SELECT #TEMPSTRING_RIGHT = CASE #TEMPSTRING_RIGHT
WHEN 'MC' THEN 'Military Contracting'
WHEN 'NP' THEN 'Nuclear'
WHEN 'OG' THEN 'Oil & Gas'
WHEN 'OS' THEN 'Oil Sands'
WHEN 'PM' THEN 'Palm Oil'
WHEN 'PE' THEN 'Pesticides'
ELSE #TEMPSTRING_RIGHT
END
END
END
SET #COUNTER = #COUNTER - 1
END
SET #Result = CONCAT(#TEMPSTRING,';', #TEMPSTRING_RIGHT)
END
ELSE
BEGIN
SET #Result = REPLACE(#Result, 'MC', 'Military Contracting')
SET #Result = REPLACE(#RESULT, 'NP', 'Nuclear Power')
SET #Result = REPLACE(#Result, 'OG', 'Oil & Gas')
SET #Result = REPLACE(#Result, 'OS', 'Oil Sands')
SET #Result = REPLACE(#Result, 'PM', 'Palm Oil')
SET #Result = REPLACE(#Result, 'PE', 'Pesticides')
END
-- Return the result of the function
RETURN #Result
END
First for some easily consumable sample data:
DECLARE #tranlation TABLE(tCode VARCHAR(10), tString VARCHAR(40));
DECLARE #t TABLE(String VARCHAR(1000));
INSERT #t VALUES('PE;N'),('NP'),('NP;MC;PE;XX')
INSERT #tranlation VALUES ('N','Nukes'),('NP','Nuclear Power'),('MC','Military'),
('PE','Pesticides');
Note my updated sample data which includes "XX", which has no match , and an "N" for "Nukes" which would wreck any solution which leverages REPLACE. If you are on SQL 2016+ you can use STRING_SPLIT and STRING_AGG.
SELECT
OldString = t.String,
NewString = STRING_AGG(ISNULL(tx.tString,items.[value]),';')
FROM #t AS t
OUTER APPLY STRING_SPLIT(t.String,';') AS items
LEFT JOIN #tranlation AS tx
ON items.[value] = tx.tCode
GROUP BY t.String ;
Returns:
OldString NewString
----------------- -------------------------------------------
NP Nuclear Power
NP;MC;PE;XX Nuclear Power;Military;Pesticides;XX
PE;N Pesticides;Nukes
You should really fix your table design so that you do not store multiple pieces of info in one column.
If you would like it as a function, I would strongly recommend an inline Table-Valued function rather than a scalar function.
If you have SQL Server version 2017+ you can use STRING_SPLIT and STRING_AGG for this.
CREATE OR ALTER FUNCTION GetFullStr
( #str varchar(250) )
RETURNS TABLE
AS RETURN
(
SELECT STRING_AGG(ISNULL(v.FullStr, s.value), ';') result
FROM STRING_SPLIT(#str, ';') s
LEFT JOIN (VALUES
('MC', 'Military Contracting'),
('NP', 'Nuclear'),
('OG', 'Oil & Gas'),
('OS', 'Oil Sands'),
('PM', 'Palm Oil'),
('PE', 'Pesticides')
) v(Abbr, FullStr) ON v.Abbr = s.value
);
GO
You can, and should, replace the VALUES with a real table.
On 2016 you would need FOR XML PATH instead of STRING_AGG:
CREATE OR ALTER FUNCTION GetFullStr
( #str varchar(250) )
RETURNS TABLE
AS RETURN
(
SELECT STUFF(
(SELECT ';' + ISNULL(v.FullStr, s.value)
FROM STRING_SPLIT(#str, ';') s
LEFT JOIN (VALUES
('MC', 'Military Contracting'),
('NP', 'Nuclear'),
('OG', 'Oil & Gas'),
('OS', 'Oil Sands'),
('PM', 'Palm Oil'),
('PE', 'Pesticides')
) v(Abbr, FullStr) ON v.Abbr = s.value
FOR XML PATH(''), TYPE
).value('text()[1]','varchar(2500)'),
, 1, 1, '')
);
GO
You use it like this:
SELECT s.result AS FullStr
FROM table
OUTER APPLY GetFullStr(value) AS s;
-- alternatively
SELECT (SELECT * FROM GetFullStr(value)) AS FullStr
FROM table;
You could assign your abbreviation mappings to a TABLE variable and then use that for your REPLACE. You could build this into a function, then pass your string values in.
The test below returns Military:Nuclear Power:XX.
declare #mapping table (abbrev varchar(50), fullname varchar(100))
insert into #mapping(abbrev, fullname)
values ('NP','Nuclear Power'),
('MC','Military')
declare #testString varchar(100), #newString varchar(100)
set #teststring = 'MC:NP:XX'
set #newString = #testString
SELECT #newString = REPLACE(#newString, abbrev, fullname) FROM #mapping
select #newString
I want to assign the value returned from the sp_formCreateEventID stored procedure into a new variable (#eventId). I initially thought this was the way to go. This solution is also in line with the EXEC command generated by SSMS.
However, for some reason the EXEC line returns an INT from the stored procedure as expected, but when it cant' assigned it's value to the #eventId variable.
DECLARE #eventId INT
EXEC #eventId = sp_formCreateEventID #patientId, #programId, #clinicianId, #formId, #phaseTypeId, #draft, #dataCollectionDate, NULL
SELECT #eventId
sp_formCreateEventID (don't hate me, I didn't write this...):
ALTER PROCEDURE [dbo].[sp_formCreateEventID]
#PatientID int,
#ProgramID int,
#ClinicianID int,
#FormID int,
#PhaseTypeID int,
#Draft varchar(5),
#CompletedDate varchar(40),
#UserID int = null
AS
BEGIN
IF #CompletedDate = ''
SET #CompletedDate = NULL
--for some forms such as Clinical Input - Initial, there should only have one form filled for a youth. If that is the case and the event has existed, just return that one.
DECLARE #EID int
SET #EID = dbo.fn_GetExistingOnlyOneEventID(#PatientID, #ProgramID, #FormID)
PRINT #eid
IF #EID <> -99
BEGIN
SELECT
#EID AS 'EventID'
RETURN
END
DECLARE #TxCycleID int
DECLARE #TxCyclePhaseTypeID int
DECLARE #TxCyclePhaseID int
DECLARE #seqNum int
DECLARE #NewEventID INT
--if there is no cycle for this patient for this program, then create one.
IF NOT EXISTS (SELECT * FROM TxCycle WHERE PatientID = #PatientID AND ProgID = #ProgramID)
BEGIN
INSERT INTO TxCycle
(OpenDate, PatientID, ProgID)
VALUES
(GETDate(), #PatientID, #ProgramID)
END
SELECT
#TxCycleID = Max(TxCycleID)
FROM TxCycle
WHERE
PatientID = #PatientID AND
ProgID = #ProgramID
--In this cycle, for the current phase type, get the max seq number
IF EXISTS (SELECT * FROM TxCyclePhase WHERE TxCycle = #TxCycleID)
BEGIN
SELECT
#seqNum = MAX(SeqNum)
FROM
TxCyclePhase
WHERE
TxCycle = #TxCycleID
SET #seqNum = #seqNum + 1
END
ELSE
BEGIN
SET #seqNum = 1
END
PRINT 'New Seq Num: ' + CONVERT(Varchar(5),#seqNum)
--greate a new seq number under the same phase
INSERT INTO TxCyclePhase
(Type, seqNum, TxCycle)
VALUES
(#PhaseTypeID, #seqNum, #TxCycleID)
--get the new ID, this will be used for the Event
SELECT
#TxCyclePhaseID = Max(TxCyclePhaseID)
FROM
TxCyclePhase
DECLARE #isFinal int
IF #Draft = 'Yes'
BEGIN
SET #isFinal = 0
END
ELSE
BEGIN
SET #isFinal = 1
END
IF EXISTS(SELECT * FROM LoginPassword WHERE ClinID = #ClinicianID AND AccessID IN (1,3))
BEGIN
IF NOT EXISTS (SELECT * FROM ClinPat WHERE ClinID = #ClinicianID AND PatientID = #PatientID)
BEGIN
INSERT INTO
ClinPat
(ClinID, PatientID)
VALUES
(#ClinicianID, #PatientID)
END
END
INSERT INTO FormPat
(PatientID, ClinID, FormID, TxCyclePhase, Date, Final, DataCollectionDate)
VALUES
(#PatientID, #ClinicianID, #FormID, #TxCyclePhaseID, GETDATE(), #isFinal, #CompletedDate)
SELECT #NewEventID = Scope_Identity()
SELECT #NewEventID AS 'EventID'
What am I doing wrong?
You need a RETURN at the bottom of your procedure.
RETURN #NewEventID
Here is a complete but simple example:
CREATE PROCEDURE [dbo].[uspExampleOne]
#Parameter1 INT
AS
BEGIN
SET NOCOUNT ON
RETURN 333
SET NOCOUNT OFF
END
GO
and
Declare #MyValue INT
EXEC #MyValue = [dbo].[uspExampleOne] 111
SELECT '#MyValueHere' = #MyValue
Result:
#MyValueHere
333
But a better design IMHO is to use an OUTPUT variable:
Why?
What happens when you need a second OUTPUT? What happens when the needed value is not an INT?
ALTER PROCEDURE [dbo].[uspExampleOne]
#Parameter1 INT ,
#OutParameter2 INT OUT
AS
BEGIN
SET NOCOUNT ON
Select #OutParameter2 = 444
RETURN 333
SET NOCOUNT OFF
END
GO
and
Declare #MyValue INT
Declare #OutParameterTwo INT
EXEC #MyValue = [dbo].[uspExampleOne] 111 , #OutParameterTwo OUT
SELECT '#MyValueHere' = #MyValue
Select '#OutParameterTwoHere' = #OutParameterTwo
Output
#MyValueHere
333
#OutParameterTwoHere
444
Below shows what I mean about "future proofing" with OUTPUT parameters
ALTER PROCEDURE [dbo].[uspExampleOne]
#Parameter1 INT ,
#OutParameter2 INT OUT,
#OutParameter3 VARCHAR(128) OUT
AS
BEGIN
SET NOCOUNT ON
Select #OutParameter2 = 444
Select #OutParameter3 = 'Better Design With Output Parameters. Not stuck with 1 return-value or data-type'
RETURN 0 /* everything went ok */
SET NOCOUNT OFF
END
GO
and the call to it
Declare #MyValue INT
Declare #OutParameterTwo INT
Declare #OutParameterThree VARCHAR(128)
EXEC #MyValue = [dbo].[uspExampleOne] 111 , #OutParameterTwo OUT , #OutParameterThree OUT
SELECT '#MyValueHere' = #MyValue
Select '#OutParameterTwoHere' = #OutParameterTwo , '#OutParameterThreeHere' = #OutParameterThree
and output
#OutParameterTwoHere #OutParameterThreeHere
444 Better Design With Output Parameters. Not stuck with 1 return-value or data-type
UPDATE SampleTable
SET Schemaname = #SchemaName,
SchemaCode = #SchemaCode,
ForeignKeyColumn = #ForeignKeyColumn,
IsChildSchema = #IsChildSchema,
ModifiedBy = #ModifiedBy,
ModifiedDate = #ModifiedDate
WHERE
DataSchemaID = #DataSchemaId
My #ForeignKeyColumn parameter is
2233^SITE_CLM_NUMBER,2236^SITE_ID_N,
Can anyone help me in updating ForeignKeyColumn='SITE_CLM_NUMBER' where DataSchemaID=2233 and ForeignKeyColumn='SITE_ID_N' where DataSchemaID=2236
It's easy to pass multiple parameter values to a query, using a Table Valued Parameter. These are available in all versions of SQL Server since 2008.
First, you need to create a Table type with the fields you want:
CREATE TYPE dbo.KeyValueType AS TABLE
( Key int, Value nvarchar(50) )
This allows you to specify a parameter of type KeyValueType with the Key/Value combinations you want, eg #updatedColumns.
You can join the target table with the TVP to update rows with matching DataSchemaID values:
Create Procedure UpdateSchemas(...., #updatedColumns dbo.KeyValueType)
UPDATE SampleTable
SET
Schemaname=#SchemaName
,SchemaCode=#SchemaCode
,ForeignKeyColumn=t.Value
,IsChildSchema=#IsChildSchema
,ModifiedBy=#ModifiedBy
,ModifiedDate=#ModifiedDate
FROM SampleTable
INNER JOIN #updatedColumns t
ON t.ID=DataSchemaID
You can add an SplitString function, like this one :
How to Split String by Character into Separate Columns in SQL Server
CREATE FUNCTION [dbo].[Split]
(
#String varchar(max)
,#Delimiter char
)
RETURNS #Results table
(
Ordinal int
,StringValue varchar(max)
)
as
begin
set #String = isnull(#String,'')
set #Delimiter = isnull(#Delimiter,'')
declare
#TempString varchar(max) = #String
,#Ordinal int = 0
,#CharIndex int = 0
set #CharIndex = charindex(#Delimiter, #TempString)
while #CharIndex != 0 begin
set #Ordinal += 1
insert #Results values
(
#Ordinal
,substring(#TempString, 0, #CharIndex)
)
set #TempString = substring(#TempString, #CharIndex + 1, len(#TempString) - #CharIndex)
set #CharIndex = charindex(#Delimiter, #TempString)
end
if #TempString != '' begin
set #Ordinal += 1
insert #Results values
(
#Ordinal
,#TempString
)
end
return
end
Now you can easily extract each part of your input parameter.
declare #I int;
declare #TMP nvarchar(255);
set #I = 1;
set #TMP = null;
set #TMP = (select StringValue from Split(#ForeignKeyCoumn, ',') where Ordinal = 1);
while #TMP <> null
begin
set #ForeignKeyColumn = (select StringValue from Split(#TMP, '^') where Ordinal = 1);
set #DataSchemaID = (select StringValue from Split(#TMP, '^') where Ordinal = 2);
-- Update here your table with #ForeignKeyColumn and #DataSchemaID values
set #I = #I + 1;
set #TMP = null;
set #TMP = (select StringValue from Split(#ForeignKeyCoumn, ',') where Ordinal = #I);
end
PS: If your are using SQL Server 2016 it already includes an SplitString function, so you won't need to add your own. https://learn.microsoft.com/en-us/sql/t-sql/functions/string-split-transact-sql
My code is:
Declare #Users table(Names nvarchar(50) not null, Flag int);
Declare #ValidUsers table(Names nvarchar(50) not null);
Declare #Office int;
Declare #NumberOfRecords int;
Declare #Count int;
Declare #IntCount int;
Declare #Binary AS nvarchar(16);
Declare #bit as nvarchar(1);
Declare #PermissionSub as nvarchar(1);
Declare #Permission as nvarchar(16);
Declare #ShouldContinue as bit;
set #ShouldContinue = 1;
set #Permission = '0001111111111111'; /* going to pass this value */
set #Count = '1';
set #IntCount = '1';
set #Office = '3'; /* going to pass this value */
Insert into #Users
Select
dbUser.usrFullName, udFeeEarnerLicence.purchaseFlag
From
[OMSBB].[dbo].[udFeeEarnerLicence]
Inner Join
[OMSBB].[dbo].[dbUser] ON udFeeEarnerLicence.feeUsrId = dbUser.usrID
Where
dbUser.brId = #Office;
select #NumberOfRecords = COUNT(Flag) from #Users;
DECLARE #Flag AS int;
select #Flag = Flag from #Users;
while(#Count <= #NumberOfRecords)
begin
WITH CTE AS
(
SELECT
Flag, ROW_NUMBER() OVER (ORDER BY Flag) AS RwNr
FROM
#Users
)
SELECT TOP(1) #Flag = Flag -- this TOP(1) is just a fail-safe
FROM CTE
WHERE RwNr = #Count;
WITH A AS
(
SELECT 0 AS ORD, #Flag AS NUMBER, CAST('' AS VARCHAR(20)) AS BITS
UNION ALL
SELECT ORD+1, NUMBER/2, CAST(BITS+CAST(NUMBER%2 AS VARCHAR(20)) AS VARCHAR(20))
FROM A
WHERE NUMBER > 0
)
SELECT #Binary = RIGHT('000000000000000'+ CASE WHEN BITS='' THEN '0' ELSE REVERSE(BITS) END,16)
FROM A
WHERE NUMBER = 0;
WHILE (#IntCount <= 16)
BEGIN
select #bit = SUBSTRING(#Binary, #IntCount, #IntCount + 1);
select #PermissionSub = SUBSTRING(#Permission, #IntCount, #IntCount + 1);
if(#PermissionSub = '1' and #bit != '1') /* if Permission selection is required and user does not have permission*/
begin
SET #ShouldContinue = 0;
break;
end
end
Set #IntCount = 0;
if(#ShouldContinue = 0)
begin
continue;
end
; WITH CTE AS
(
SELECT Names, ROW_NUMBER() OVER (ORDER BY Flag) AS RwNr
FROM #Users
)
INSERT INTO #ValidUsers
SELECT Names
FROM CTE
WHERE RwNr = #Count;
end
select * from #ValidUsers
I will be adapting this code to use it inside of an SSRS report so that's why there are comments on some parameters saying that I will be passing the parameters. This code at its basics finds all users who are from a specified office and have the specified permissions. The permission a user has are set in 5 flags in this example I'm using the purchaseFlag. This value is an int and it calculated by creating an order of permissions and set their bit values to create a string of 0's and 1's and then converting that binary number into a decimal for example '8191' which the binary value of would be '0001111111111111'. I use two while loops in this one to go through the users and the other to go through each of the 16 characters in the permissions. My issue is that this I'm almost certain that this query works but it takes so long to run that I haven't seen the result of it yet and people have recommended that I use sets instead.
I am having issues converting a portion of my script that works in Oracle over for use in SQL Server. The portion of my script uses arrays and I have not been able to find the equivalent in TSQL (I dont believe one exists?). My main issues occur when trying to match values v_measure_map(i).v_upload_code = b.UPLOAD_CODE. Any tips or suggestions?
SELECT SCOPE_KEY,
ENRICHED_DATE,
ENRICHED_TIME,
BENCHMARK_DATE,
PROSDEALID
INTO v_xs_scope
FROM xaction_scope
WHERE TXN_ID = V_TXN_ID ;
<<loop2>> FOR i IN 1..v_measure_map.count --count returns the number of rows in the table (sy_enrich_measure_map)
LOOP
<<loop3>> FOR j IN 1..v_xs_scope.count
LOOP
SELECT COUNT(*)
INTO #v_sql_count
FROM xaction_Level_info b
WHERE v_measure_map(i).v_upload_code = b.UPLOAD_CODE
AND v_xs_scope(j).v_scope_key = b.SCOPE
AND
Use table variables, for example:
DECLARE
#v_xs_scope TABLE (
RowNum INT IDENTITY,
SCOPE_KEY INT,
ENRICHED_DATE DATE,
ENRICHED_TIME TIME,
BENCHMARK_DATE DATE,
PROSDEALID INT
)
DECLARE
#v_measure_map TABLE (
RowNum INT IDENTITY,
v_upload_code INT
)
INSERT INTO #v_xs_scope (
SCOPE_KEY, ENRICHED_DATE, ENRICHED_TIME, BENCHMARK_DATE, PROSDEALID
)
SELECT
SCOPE_KEY, ENRICHED_DATE, ENRICHED_TIME, BENCHMARK_DATE, PROSDEALID
FROM xaction_scope
WHERE
TXN_ID = V_TXN_ID;
INSERT INTO #v_measure_map(v_upload_code)
SELECT v_upload_code
FROM v_measure_map
DECLARE
#l1_CurrentRowNum INT,
#l1_MaxRowNum INT,
#l2_CurrentRowNum INT,
#l2_MaxRowNum INT,
#v_upload_code INT,
#v_scope_key INT
SELECT
#l1_CurrentRowNum = 1,
#l1_MaxRowNum = MAX(RowNum)
FROM #v_measure_map
WHILE #l1_CurrentRowNum <= #l1_MaxRowNum
BEGIN
SELECT #v_upload_code = v_upload_code
FROM #v_measure_map
WHERE
RowNum = #l1_CurrentRowNum
SELECT
#l2_CurrentRowNum = 1,
#l2_MaxRowNum = MAX(RowNum)
FROM #v_xs_scope
WHILE #l2_CurrentRowNum <= #l2_MaxRowNum
BEGIN
SELECT #v_scope_key = scope_key
FROM #v_xs_scope
WHERE
RowNum = #l2_CurrentRowNum
SELECT #v_sql_count = COUNT(*)
FROM xaction_Level_info b
WHERE
b.UPLOAD_CODE = #v_upload_code
AND b.SCOPE = #v_scope_key
SET #l2_CurrentRowNum = #l2_CurrentRowNum + 1
END
SET #l1_CurrentRowNum = #l1_CurrentRowNum + 1
END
or cursors, for example:
DECLARE
#v_upload_code INT,
#v_scope_key INT
DECLARE curs_1 CURSOR FOR
SELECT
v_upload_code
FROM v_measure_map
OPEN curs_1;
FETCH curs_1 INTO #v_upload_code;
WHILE (##FETCH_STATUS<>-1)
BEGIN
DECLARE curs_2 CURSOR FOR
SELECT
SCOPE_KEY
FROM xaction_scope
WHERE
TXN_ID = V_TXN_ID
OPEN curs_2;
FETCH curs_2 INTO #v_scope_key;
WHILE (##FETCH_STATUS<>-1)
BEGIN
SELECT #v_sql_count = COUNT(*)
FROM xaction_Level_info b
WHERE
b.UPLOAD_CODE = #v_upload_code
AND b.SCOPE = #v_scope_key
FETCH curs_2 INTO #v_scope_key;
END
CLOSE curs_2;
DEALLOCATE curs_2;
FETCH curs_1 INTO #v_upload_code;
END
CLOSE curs_1;
DEALLOCATE curs_1;