I need to get the first and last name, but the maximum in the first name is 30 characters
declare #name nvarchar(250)='David Judith and Holofernes Equestrian of Gattamelata'
SELECT LEFT(rtrim(#name), LEN(rtrim(#name)) - CHARINDEX(' ',REVERSE(rtrim(#name)))) 'firstName'
SELECT RIGHT(rtrim(#name), CHARINDEX(' ',REVERSE(rtrim(#name)))-1) 'lastName'
result of my attempt:
Firstname=David Judith and Holofernes Equestrian of
Lastname=Gattamelata
the end result I want:
Firstname=David Judith and Holofernes
Lastname=Equestrian of Gattamelata
That is, it must be placed after 30 characters in the last name.
try again, now i need to optimize this code below:
declare #name nvarchar(250)='David Judith and Holofernes Equestrian of Gattamelata'
SELECT value FROM STRING_SPLIT(#name, ' ');
DECLARE #firstName as NVARCHAR(50)='';
DECLARE #lastName as NVARCHAR(50)='';
DECLARE #value as NVARCHAR(50);
DECLARE #NamesCursor as CURSOR;
SET #NamesCursor = CURSOR FORWARD_ONLY FOR
SELECT value
FROM STRING_SPLIT(#name, ' ');
OPEN #NamesCursor;
FETCH NEXT FROM #NamesCursor INTO #value;
WHILE ##FETCH_STATUS = 0
BEGIN
print #value
print len(#firstname)
if (len(#firstname) < 30 and len(isnull(#firstname,'') + #value) < 30)
set #firstname=isnull(#firstname,'') + #value + ' '
else
set #lastName=isnull(#lastName,'') + #value + ' '
print #firstname
FETCH NEXT FROM #NamesCursor INTO #value;
END
CLOSE #NamesCursor;
DEALLOCATE #NamesCursor;
select rtrim(ltrim(#firstname)) 'First Name', rtrim(ltrim(#lastName)) 'Last Name'
thanks
Related
I have a procedure that has a nested cursor to return the rooms of the hotel, with a nested cursor inside that cursor to return the cost for that room over the different periods of time. However, when I run my procedure, I get the hotel id and name (as I should), the room name and description (as I should), but then the first cost value gets infinitely printed out.
CREATE PROCEDURE sp_GetRackRates
#HotelID smallint
AS
BEGIN
DECLARE #HotelName varchar(30)
DECLARE #RoomID smallint
DECLARE #RoomNumber smallint
DECLARE #RTDescription varchar(200)
DECLARE #RackRate smallmoney
DECLARE #RackRateBegin date
DECLARE #RackRateEnd date
SELECT #HotelName = HotelName
FROM Hotel
WHERE HotelID = #HotelID
PRINT 'Hotel ID: ' + CAST(#HotelID AS varchar(max)) + ' - ' + CAST(#HotelName as
varchar(max))
PRINT ' '
SELECT #RoomID = RoomID, #RoomNumber = RoomNumber, #RTDescription = RTDescription
FROM (Room
INNER JOIN RoomType ON Room.RoomTypeID = RoomType.RoomTypeID)
WHERE Room.HotelID = #HotelID
SELECT #RackRate = RackRate, #RackRateBegin = RackRateBegin, #RackRateEnd =
RackRateEnd
FROM (RackRate
INNER JOIN Room ON RackRate.HotelID = Room.HotelID)
WHERE RackRate.HotelID = #HotelID AND RoomNumber = #RoomNumber
DECLARE cr_GetRoom CURSOR
FOR
SELECT RoomID, RoomNumber, RTDescription
FROM (Room
INNER JOIN RoomType ON Room.RoomTypeID = RoomType.RoomTypeID)
WHERE Room.HotelID = #HotelID
DECLARE cr_GetRackRates CURSOR
FOR
SELECT RackRate, RackRateBegin, RackRateEnd
FROM (RackRate
INNER JOIN Room ON RackRate.HotelID = Room.HotelID)
WHERE RackRate.HotelID = #HotelID AND RoomNumber = #RoomNumber
OPEN cr_GetRoom
FETCH NEXT FROM cr_GetRoom
INTO #RoomID, #RoomNumber, #RTDescription
WHILE ##FETCH_STATUS = 0
BEGIN
PRINT 'Room ' + CAST(#RoomNumber AS varchar(max)) + ': ' + CAST(#RTDescription
as varchar(max))
OPEN cr_GetRackRates
FETCH NEXT FROM cr_GetRackRates
INTO #RackRate, #RackRateBegin, #RackRateEnd
WHILE ##FETCH_STATUS = 0
BEGIN
PRINT 'Rate: $' + CAST(#RackRate as varchar(max)) + ' valid ' +
cast(#RackRateBegin AS varchar(max)) + ' to ' + CAST(#RackRateEnd AS
varchar(max))
END
CLOSE cr_GetRackRates
PRINT ' '
END
CLOSE cr_GetRoom
DEALLOCATE cr_GetRackRates
DEALLOCATE cr_GetRoom
END
A Sample output looks as follows:
HotelID: 2100 - Sunridge B&B
Room 101: Single
Rate: $125.00 valid 2023-03-16 to 2023-11-14
Rate: $125.00 valid 2023-03-16 to 2023-11-14
Rate: $125.00 valid 2023-03-16 to 2023-11-14
Rate: $125.00 valid 2023-03-16 to 2023-11-14
Rate: $125.00 valid 2023-03-16 to 2023-11-14
Rate: $125.00 valid 2023-03-16 to 2023-11-14
Rate: $125.00 valid 2023-03-16 to 2023-11-14
Where the Rate: $125.00 continues infinitely, even though there is only one of those values in the database.
Why does the nested cursor keep repeating the same value? I've tried using SELECT DISTINCT but it kept giving the same results.
I figured out what my issue was.
In the blocks
FETCH NEXT FROM cr_GetRoom
INTO #RoomID, #RoomNumber, #RTDescription
WHILE ##FETCH_STATUS = 0
BEGIN
PRINT 'Room ' + CAST(#RoomNumber AS varchar(max)) + ': ' + CAST(#RTDescription
as varchar(max))
OPEN cr_GetRackRates
FETCH NEXT FROM cr_GetRackRates
INTO #RackRate, #RackRateBegin, #RackRateEnd
WHILE ##FETCH_STATUS = 0
BEGIN
PRINT 'Rate: $' + CAST(#RackRate as varchar(max)) + ' valid ' +
cast(#RackRateBegin AS varchar(max)) + ' to ' + CAST(#RackRateEnd AS
varchar(max))
END
CLOSE cr_GetRackRates
PRINT ' '
END
I was not fetching the next item, so it was just sitting at the same item constantly returning it.
It should be:
FETCH NEXT FROM cr_GetRoom
INTO #RoomID, #RoomNumber, #RTDescription
WHILE ##FETCH_STATUS = 0
BEGIN
PRINT 'Room ' + CAST(#RoomNumber AS varchar(max)) + ': ' + CAST(#RTDescription
as varchar(max))
OPEN cr_GetRackRates
FETCH NEXT FROM cr_GetRackRates
INTO #RackRate, #RackRateBegin, #RackRateEnd
WHILE ##FETCH_STATUS = 0
BEGIN
PRINT 'Rate: $' + CAST(#RackRate as varchar(max)) + ' valid ' +
cast(#RackRateBegin AS varchar(max)) + ' to ' + CAST(#RackRateEnd AS
varchar(max))
FETCH NEXT FROM cr_GetRackRates
INTO #RackRate, #RackRateBegin, #RackRateEnd
END
CLOSE cr_GetRackRates
PRINT ' '
FETCH NEXT FROM cr_GetRoom
INTO #RoomID, #RoomNumber, #RTDescription
END
You seem to mix cursors with regular variable fetching and not doing actual loops, and declaring the cursors in wrong position so i'm gonna assume your fixed code doesn't work, so please forgive me if my assumption is not correct.
The improved(?) version:
CREATE PROCEDURE spGetRackRates
#HotelID smallint
AS
BEGIN
DECLARE #HotelName varchar(30)
DECLARE #RoomID smallint
DECLARE #RoomNumber smallint
DECLARE #RTDescription varchar(200)
DECLARE #RackRate smallmoney
DECLARE #RackRateBegin date
DECLARE #RackRateEnd date
SELECT #HotelName = HotelName
FROM Hotel
WHERE HotelID = #HotelID
PRINT 'Hotel ID: ' + CAST(#HotelID AS varchar(max)) + ' - ' + CAST(#HotelName as
varchar(max))
PRINT ' '
DECLARE cr_GetRoom CURSOR READ_ONLY FORWARD_ONLY LOCAL STATIC FOR
SELECT RoomID, RoomNumber, RTDescription
FROM Room
INNER JOIN RoomType ON Room.RoomTypeID = RoomType.RoomTypeID
WHERE Room.HotelID = #HotelID
OPEN cr_GetRoom
WHILE 1 = 1
BEGIN
FETCH NEXT FROM cr_GetRoom
INTO #RoomID, #RoomNumber, #RTDescription
IF ##FETCH_STATUS <> 0
BREAK
DECLARE cr_GetRackRates CURSOR READ_ONLY FORWARD_ONLY LOCAL STATIC FOR
SELECT RackRate, RackRateBegin, RackRateEnd
FROM RackRate
INNER JOIN Room ON RackRate.HotelID = Room.HotelID
WHERE RackRate.HotelID = #HotelID AND RoomNumber = #RoomNumber
OPEN cr_GetRackRates
WHILE 1 = 1
BEGIN
FETCH NEXT FROM cr_GetRackRates
INTO #RackRate, #RackRateBegin, #RackRateEnd
IF ##FETCH_STATUS <> 0
BREAK
PRINT 'Room ' + CAST(#RoomNumber AS varchar(max)) + ': ' + CAST(#RTDescription as varchar(max))
PRINT 'Rate: $' + CAST(#RackRate as varchar(max)) + ' valid ' +
cast(#RackRateBegin AS varchar(max)) + ' to ' + CAST(#RackRateEnd AS
varchar(max))
END
PRINT ' '
CLOSE cr_GetRackRates
DEALLOCATE cr_GetRackRates
END
CLOSE cr_GetRoom
DEALLOCATE cr_GetRoom
END
A couple of points:
Unless you want to update data, you should declare your cursors as local static, which avoids pollution the namespace of cursors, and also improve your performance.
You have to declare the inner cursor "inside" the loop after your fetch the room number, otherwise it just becomes static bound to the original room variable.
I prefer to use WHERE 1 = 1 loops and check for fetch_status after the fetching of variables. This is because a lot of times one forgets to fetch the variables again in the end of the loop which messes things up.
What is want to do is the following:
declare #Count numeric (10)
set #Count = 0
set #Count = (select count(*) from FILENAME where COLUMNNAME like '%e%')
print(#tel)
I want it do be done on a few files that have a lot of columns and have a total count for all the columns, so my idea was to get a columnlist of each file by doint something like:
select * from sys.columns
where object_id = ( select object_id from sys.objects where name = 'FILENAME')
Now the easiest way i thought would be using a cursor and have the #Counts added up there in another variable. But the problem i am having is that when COLUMNNAME is in a variable in the cursor i can only (as far as i know) make the query like:
declare #SQL varchar(max)
set #SQL = #SQL + 'set #Count = (select count(*) from FILENAME where '
+ #columnname + ' like ''%e%'' )'
set #tot_Count = #tot_Count + #Count
But as I understand from reading around dynamic sql inside a cursor is a big no.
And though when i see the "print (sql)" the queries seem to be right it doesnt seem to work indeed in a cursos.
Is there another way to get the results i want?
Or am i doing something wrong here?
For reference, this was the idea i had in total:
DECLARE #columnname VARCHAR(50)
DECLARE #tot_Count NUMERIC(10), #Count NUMERIC(10)
set #tot_Count = 0
DECLARE MyCursor CURSOR FOR
SELECT name
from sys.columns
where object_id = ( select object_id from sys.objects where name = 'FILENAME' )
open MyCursor
FETCH NEXT FROM MyCursor INTO #columnname
WHILE ##FETCH_STATUS = 0
BEGIN
declare #SQL varchar(max)
set #SQL =''
set #Count = 0
set #SQL = #SQL + 'set #teller = (select count(*) from FILENAME where ' + #columnname + ' like ''%e%'' )'
print (#SQL)
exec (#SQL)
set #tot_Count = #tot_Count + #Count
FETCH NEXT FROM MyCursor into #name
END
CLOSE MyCursor
DEALLOCATE MyCursor
print (#tot_teller)
Variant 1: You can use dynamic variable instead of cursor operation.
declare #qry varchar(max)
select #qry = isnull(#qry + ' union all', '') + ' select count(*) cnt from ' + object_name(object_id) + ' where ' + name + ' like ''%e%'''
from sys.columns
where object_id = object_id('YourTableName')
set #qry = 'select sum(cnt) from (' + #qry + ') q'
print #qry
exec (#qry)
It's shorter, better, but exec is limited by 4000 chars.
Variant 2: Or you can use your cursor and via dynamic qry insert into your preprepared temp table.
if object_id('tempdb..#tmptbl') is not null drop table #tmptbl
create table #tmptbl (cnt int not null)
declare #colqry varchar(800)
declare mycursor cursor for
select 'insert into #tmptbl (cnt) select count(*) cnt from ' + object_name(object_id) + ' where ' + name + ' like ''%e%'''
from sys.columns
where object_id = object_id('YourTableName')
open mycursor
fetch next from mycursor into #colqry
while ##fetch_status = 0
begin
print #colqry
exec (#colqry)
fetch next from mycursor into #colqry
end
close mycursor
deallocate mycursor
select sum(cnt) from #tmptbl
DECLARE #tot_Count int = 0
DECLARE #Separator varchar(1) = ','
DECLARE #Position INT = 1
DECLARE #ColumnNameList varchar(MAX)
DECLARE #ColumnName varchar(1000)
DECLARE #SQL varchar(max) = ''
SET #ColumnNameList = STUFF(( SELECT name
from sys.columns
where object_id in ( select object_id from sys.objects where name = 'FILENAME' ) FOR XML PATH('')),1,1,'')+','
--print #FileNameList
WHILE (CHARINDEX(#Separator,#ColumnNameList,#Position)!=0)
BEGIN
SET #ColumnName = SUBSTRING(#ColumnNameList,#Position,CHARINDEX(#Separator,#ColumnNameList,#Position)-#Position)
SET #SQL = #SQL + 'set #tot_Count = (select count(*) from FILENAME where ' + #ColumnName + ' like ''%e%'' )'
-- print (#SQL)
EXEC (#SQL)
SET #tot_Count = #tot_Count + #tot_Count
SET #Position = CHARINDEX(#Separator,#ColumnNameList,#Position)+1
END
PRINT (#tot_Count)
Currently I have a dynamic query, generated in the stored procedure, that has a bug. Somehow there is a consecutive duplicate 'AND' generated in it.
Wondering if there is a way to delete the CONSECUTIVE DUPLICATE 'AND' from the dynamic query string.
For eg:
var str = 'Select * from employee A where A.age > 30 AND AND A.role = ''developer'''
Update
The replace as suggested below doesnt work
Please see the below query:
DECLARE
#str NVARCHAR(MAX)
SET #str = 'fasdf asdfasf asfasdfasafsdf AND AND asdfasdfasd AND dfasdfa'
SET #str = REPLACE(#str, 'AND AND', 'AND')
PRINT #str
Thanks!
Something like this?
/****** Object: StoredProcedure [dbo].[RemoveConsecutiveDuplicateTokens] Script Date: 30/06/2016 09:30:50 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE procedure [dbo].[RemoveConsecutiveDuplicateTokens]
#instr varchar(max) ,
#outstr varchar(max) OUTPUT
as
declare #workstr varchar(max) = ltrim(#instr),
#newstr varchar(max),
#oldtoken varchar(max),
#newtoken varchar(max)
while #workstr is not null
begin
if #oldtoken is null
begin
set #oldtoken = SUBSTRING(#workstr,1,charindex(' ',#workstr))
set #workstr = ltrim(Stuff(#workstr, CharIndex(#oldtoken,#workstr), Len(#oldtoken), ''))
set #newstr = #oldtoken + ' '
end
set #newtoken = SUBSTRING(#workstr,1,charindex(' ',#workstr))
if #newtoken <> #oldtoken
begin
if #newtoken <> char(39)
begin
set #oldtoken = #newtoken
set #newstr = #newstr + #newtoken + ' '
set #workstr = ltrim(Stuff(#workstr, CharIndex(#newtoken,#workstr), Len(#newtoken), ''))
end
end
else
begin
set #workstr = ltrim(Stuff(#workstr, CharIndex(#newtoken,#workstr), Len(#newtoken), ''))
end
if charindex(' ',#workstr) = 0
break
end
set #newtoken = SUBSTRING(#workstr,1,len(#workstr))
if #newtoken <> #oldtoken
begin
if #newtoken <> char(39)
begin
set #oldtoken = #newtoken
set #newstr = #newstr + #newtoken + ' '
set #workstr = ltrim(Stuff(#workstr, CharIndex(#newtoken,#workstr), Len(#newtoken), ''))
end
end
else
begin
set #workstr = ltrim(Stuff(#workstr, CharIndex(#newtoken,#workstr), Len(#newtoken), ''))
end
select #outstr = #newstr
return
First of all, you are doing it wrong. Fix the logic that generates this incorrect sql.
But for research/learning purposes, this is how you do.
REPLACE ( str , 'AND AND' , 'AND')
I forgot how much I dislike SUBSTRING, but then that has been my struggle to read <starting_position> as truly the position the value begins with.
However, the real beast was how string manipulations are implemented in SQL Server under the context of the ##TRANCOUNT.
Consider the statement
PRINT QUOTE_NAME(REPLACE('My____Table', '__', '_'))
We wish to use proper naming standards, but the function returns:
`[My__Table]`
Why? Because REPLACE jumps ahead the length of the duplicates. To prove it, lets add one more '_' CHAR(95) and we get this in return:
`[My___Table]`
So then simply embedding this with a WHILE statement, for example, will be quite sufficient for our needs. Note I replaced the spaces with '_' for readability
DECLARE #instr varchar(max)
SET #instr = 'SELECT * from employee A where A.age > 30 AND AND A.role = ''developer'''
DECLARE #workstr varchar(max) = REPLACE(LTRIM(#instr), ' ', '_'),
#tokenque VARCHAR(MAX),
#newstr INT = 0,
#token varchar(max),
#flag_break INT = 0
-- removes the extra "spaces"
WHILE CHARINDEX('__', #workstr) <> 0
BEGIN
SET #workstr = REPLACE(#workstr, '__' , '_')
END
SET #tokenque = #workstr
WHILE (CHARINDEX('_', #tokenque) <> 0)
BEGIN
SET #token = SUBSTRING(#tokenque, 1, CHARINDEX('_', #Tokenque) - 1 )
IF #token <> '''' -- (') delimiter skipped
BEGIN
WHILE CHARINDEX(#token + '_' + #token, #workstr) <> 0
BEGIN
SET #workstr = REPLACE(#workstr, #token + '_' + #token, #token)
END
SET #tokenque = SUBSTRING(#tokenque, LEN(#token) + 2, LEN(#tokenque) )
END
ELSE SET #tokenque = SUBSTRING(#tokenque, LEN(#token) + 2, LEN(#tokenque) )
PRINT #tokenque --if you want to see the progression
END
PRINT REPLACE(#workstr, '_', ' ')
RESULT:
'SELECT * from employee A where A.age > 30 AND A.role = 'developer'
use the REPLACE function and replace 'AND AND' by 'AND'. example
SELECT REPLACE('Select * from employee A where A.age > 30 AND AND A.role = ''developer'' ','AND AND','AND');
DECLARE #COLNAME VARCHAR(100)
DECLARE #CREATE VARCHAR (1000)
DECLARE #TYPE VARCHAR(1)
SET #COLNAME = ''
SET #TYPE = 5
SET #CREATE = 'CRATE TABLE TABLE_TYPE_' + #TYPE + '('
DECLARE MyCursor CURSOR FOR
SELECT Name FROM LAYOUT WHERE RecordType = #TYPE
ORDER BY Start
OPEN MyCursor
FETCH NEXT FROM MyCursor INTO #COLNAME
WHILE ##FETCH_STATUS = 0
BEGIN
SET #COLNAME = REPLACE(#COLNAME, 'WX-', '')
SET #COLNAME = REPLACE(#COLNAME, '(', '')
SET #COLNAME = REPLACE(#COLNAME, ')', '')
SET #CREATE = #CREATE + '[' + #COLNAME + ']' + ' VARCHAR(1000),'
FETCH NEXT FROM MyCursor INTO #COLNAME
END
CLOSE MyCursor
DEALLOCATE MyCursor
SET #CREATE = LEFT(#CREATE, len(#CREATE) -1) + ')' --get rid of last comma
PRINT (#CREATE) --EXEC (#CREATE)
It seem like there is the maximum limit on MS. When I print the #CREATE, many rows have been cut off.
EX. There are 300 columns but somehow it can only print out up to 200 columns
How can I gerenrate the create table statements without any cut offs.
I know some people will suggest don't use the cursor, but since there are so many columns for one table, it will be very time consuming to type out all the columns name.
You really should not use a cursor for that.
Not only is it possible to do without a cursor, it's simpler:
DECLARE #CREATE VARCHAR (max),
#TYPE int = 5
SET #CREATE = 'CRATE TABLE TABLE_TYPE_' + CAST(#TYPE as varchar) + '('
SELECT #CREATE = #CREATE + REPLACE(
REPLACE(
REPLACE([Name], 'WX-', ''),
'(', ''),
')', '') + ' VARCHAR(1000),'
FROM Layout
WHERE RecordType = #TYPE
SET #CREATE = LEFT(#CREATE, len(#CREATE) -1) + ')' --get rid of last comma
PRINT #CREATE
see fiddle here
I have following stored procedure which basically uses cursor to get people who have appointments today and sends them email. For some reason this query won't complete. When I try to execute it, it just spins and I had to stop it. I let it run for as long as 7 minutes once and still I didn't get either an error or timeout. Not sure what it is doing. Any help will be appreciated. Here is my query:
ALTER PROCEDURE [dbo].[spReminderEmail]
AS
SET NOCOUNT ON;
DECLARE #MyCursor CURSOR
DECLARE #emailBody nvarchar(max)
DECLARE #subject nvarchar(max)
DECLARE #recipients nvarchar(max)
DECLARE #appointmentDate datetime
DECLARE #doctorFirstName nvarchar(max)
DECLARE #doctorLastName nvarchar(max)
DECLARE #groupName nvarchar(max)
DECLARE #location nvarchar(max)
DECLARE #count int
SET #count = 0
SET #MyCursor = CURSOR FAST_FORWARD For
Select StartTime, PersonEmail, DoctorFirstName, DoctorLastName, GroupName, Location from vwAppointment where StartTime BETWEEN CAST(GETDATE() AS DATE) AND DATEADD(DAY, 1, CAST(GETDATE() AS DATE)) AND IsActive = 1
Open #MyCursor
FETCH NEXT FROM #MyCursor INTO #appointmentDate, #recipients, #doctorFirstName, #doctorLastName, #groupName, #location
WHILE ##FETCH_STATUS = 0
BEGIN
SET #emailBody = 'Hello from ' + #groupName + '. This is an email reminder of your appointment with ' + #doctorFirstName + ' ' + #doctorLastName + ' on ' + convert(varchar, #appointmentDate, 1) + ' at ' + #location + '.' + CHAR(13) + CHAR(10) + 'To help facilitate the meeting, please remember to bring with you any relevant documents (ID, insurance, etc.) and be prepared with questions for the office.' + CHAR(13) + CHAR(10) + 'If you are unable to make the appointment, please call ' + #groupName + ' or return to KSUAdvising and use the cancellation function. Cancellations are requested at least a day in advance.' + CHAR(13) + CHAR(10) + 'Late Policy:' + CHAR(13) + CHAR(10) + 'some text here...';
SET #subject = 'REMINDER: Your Appointment with the ' + #groupName;
SET #count = #count + 1
END
CLOSE #MyCursor
DEALLOCATE #MyCursor
PRINT #count
if (#count > 0)
BEGIN
EXEC msdb.dbo.sp_send_dbmail
#profile_name='my_profile',
#recipients=#recipients,
#body=#emailBody,
#subject=#subject
END
Inside the WHILE loop (before END line) you must add this:
FETCH NEXT FROM #MyCursor INTO #appointmentDate, #recipients,
#doctorFirstName, #doctorLastName, #groupName, #location
to scroll for every loop a record of your query
You're never fetching your next row. So your loop will go on forever doing nothing. You need to add FETCH NEXT FROM #MyCursor INTO #appointmentDate, #recipients, #doctorFirstName, #doctorLastName, #groupName, #location right before your END statment . See the example at the bottom of This
You also may try to debug your sp to find exact place of issues in you SP in the future.