insert the null record in the print lable - sql

I am trying to create a SP which print the label of my vendor, vendor name. I want the user set the startposition, before the startposition I just simply insert a null value. I want be able to reuse the label sheet.
I have the SP code like this:
Alter PROCEDURE [dbo].[z_sp_APVendorLabel]
(#VendorGroup bGroup ,
#StartPosition int)
AS
BEGIN
SET NOCOUNT ON;
Create table #data_null
(Vendor int,
Name varchar(60)null)
Declare #counter int
SET #counter = 0
WHILE #counter < #StartPosition
BEGIN
UPDATE #data_null SET Vendor='',Name=' '
SET #counter = #counter + 1
END
Create table #detial
(Vendor int,
Name varchar (60)null)
select Vendor, Name into #data from APVM
WHERE VendorGroup= #VendorGroup
select * from #data_null
Union All
select * from #detial
END
It is very simple, but when I test it, I did not get any data.

You're creating the table #data_null, and updating it, but never inserting any rows. If you inspect ##rowcount after each update, you'll see it's zero.
Before you change that loop to insert instead of update, please consider setting up a permanent table to select from. A loop to generate N values on every invocation of the procedure is really not the best use of your server's time, or yours. ;-)

Related

Set the temporary table in SQL server as variable

I am trying to create a temporary table but I need to change the name of the table based on the content of a variable as I need to create more than one table inside a while loop. Is there a way to do that?
while(#roCounter <= #insideCounter)
BEGIN
set #nameOfTable = #nameOfTable+#roCounter
select * into ##nameOfTable from #CC where ro=#roCounter --#nameOfTable is a variable
set #roCounter = #roCounter +1
END
Drop Table #CC
set #counter = #counter +1
END

Multiple rows are getting inserted into a table (which is not desired) as part of a stored procedure

Update: This still remain a mystery. Checked the calling code and we did not find anything that would make the SP run in a loop.
For now we have split the SP into two which seems to have arrested the issue although not able to reason how that has helped out.
Database: MS SQL Server.
I have a SP which performs few operations - i.e inserts a row into 3 tables based on certain status as part of that SP being called.
It is getting called from our web application based on a user action.
We have cases, few times a day where the same row gets inserted multiple times (sometime more than 50+) with the same values in each row except that if you look at the datetime when the row was inserted there is a difference of few milliseconds. So it is unlikely that the user is initiating that action.
This SP is not running in a Transaction or with any locks however it is getting called probably concurrently multiple times as we have many concurrent users on the web application invoking this action.
My question is what is causing the same row to insert so many times? If concurrent execution of SP was an issue where we are updating same row then it is understood one may overwrite the other. However in this case each user calls in the SP with different parameters.
I have put the said operation in a Transaction to monitor the behavior however was looking to find out what exactly causes these kind of multiple inserts with same value just a few milliseconds apart?
USE [ABC]
GO
/****** Object: StoredProcedure [dbo].[AddProcessAdmittedDocUploadScrutinyWithLog] ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER PROCEDURE [dbo].[AddProcessAdmittedDocUploadScrutinyWithLog]
(
--Insert using bulk
#stdfrm_id int,
#course_id int,
#stdfrm_scrt_apprvby int,
#stdfrm_scrt_apprvcomment varchar(max),
#sRemainingDocs varchar(max),
#DTProcessAdmittedDocUploadScrutiny AS dbo.MyDTProcessAdmittedDocUploadScrutiny READONLY
)
AS
BEGIN
DECLARE #result char
SET #result='N'
--New
declare #AuditCount int=0;
select #AuditCount=count(scrtaudit_id) from tbl_ProcessAdmittedScrutinyAuditLog
where stdfrm_id=#stdfrm_id and stdfrm_scrt_apprvby=#stdfrm_scrt_apprvby
and stdfrm_scrt_apprvcomment=#stdfrm_scrt_apprvcomment and convert(date,stdfrm_scrt_apprvon,103)=convert(date,getdate(),103)
--Checked extra conditon to avoid repeatation
if(#AuditCount=0)
BEGIN
--Call Insert
BEGIN TRY
/*Remaining Documents----------*/
DECLARE #sdtdoc_id Table (n int primary key identity(1,1), id int)
if(#sRemainingDocs is not null)
begin
--INSERT INTO #sdtdoc_id (id) SELECT Name from splitstring(#sRemainingDocs)
INSERT INTO #sdtdoc_id (id) SELECT [Value] from dbo.FN_ListToTable(#sRemainingDocs,',')
end
Declare #isRemaining int=0;
SELECT #isRemaining=Count(*) FROM #sdtdoc_id
/*Calculate stdfrm_scrt_apprvstatus*/
Declare #stdfrm_scrt_apprvstatus char(1)='A';--Approved
Declare #TotalDescripancies int;
select #TotalDescripancies=count(doc_id) from #DTProcessAdmittedDocUploadScrutiny where doc_id_scrtyn='Y'
if(#isRemaining>0)
begin
set #stdfrm_scrt_apprvstatus='H';--Discrepancies Found
end
else if exists (select count(doc_id) from #DTProcessAdmittedDocUploadScrutiny where doc_id_scrtyn='Y')
begin
if(#TotalDescripancies>0)
begin
set #stdfrm_scrt_apprvstatus='H';--Discrepancies Found
end
end
/* Check if Discrepancies Found first time then assign to Checker o.w assign to direct college like grievance*/
if(#stdfrm_scrt_apprvstatus='H')
begin
declare #countAuditLog int=0;
select #countAuditLog=count(stdfrm_id) from tbl_ProcessAdmittedScrutinyAuditLog where stdfrm_id =#stdfrm_id
if (#countAuditLog=0)
begin
set #stdfrm_scrt_apprvstatus='G'--'E';--Discrepancies Found set Edit request assign to Checker
end
--else if (#countAuditLog=1)
-- begin
--set #stdfrm_scrt_apprvstatus='G';--Discrepancies Found set Grievance assign to college
-- end
end
/*----------------------*/
/*Update status in original table-----*/
Update tbl_ProcessAdmitted set stdfrm_scrt_apprvstatus=#stdfrm_scrt_apprvstatus
,stdfrm_scrt_apprvon=getdate(),stdfrm_scrt_apprvby=#stdfrm_scrt_apprvby
,stdfrm_scrt_apprvcomment=#stdfrm_scrt_apprvcomment
where stdfrm_id =#stdfrm_id
/*Add in Main Student Log-----------*/
/********* The row here gets inserted multiple times *******************/
INSERT into tbl_ProcessAdmittedScrutinyAuditLog
(stdfrm_id, stdfrm_scrt_apprvstatus, stdfrm_scrt_apprvon, stdfrm_scrt_apprvby, stdfrm_scrt_apprvcomment )
values
(#stdfrm_id, #stdfrm_scrt_apprvstatus, getdate(), #stdfrm_scrt_apprvby, #stdfrm_scrt_apprvcomment)
DECLARE #scrtaudit_id int =##identity
/*Completed -------------------------*/
DELETE FROM tbl_ProcessAdmittedDocUploadScrutiny WHERE stdfrm_id =#stdfrm_id
SET NOCOUNT ON;
/********* The row here gets inserted multiple times *******************/
INSERT tbl_ProcessAdmittedDocUploadScrutiny
(stdfrm_id, course_id, doc_id, doc_id_scrtyn, doc_id_scrtrmrk, doc_id_comment)
SELECT #stdfrm_id, #course_id, doc_id, doc_id_scrtyn, doc_id_scrtrmrk, doc_id_comment
FROM #DTProcessAdmittedDocUploadScrutiny;
/*Scrutiny Document Log -------------------------*/
/********* The row here gets inserted multiple times *******************/
INSERT tbl_ProcessAdmittedDocUploadScrutinyAuditLog
(scrtaudit_id,stdfrm_id, course_id, doc_id, doc_id_scrtyn, doc_id_scrtrmrk, doc_id_comment)
SELECT #scrtaudit_id,#stdfrm_id, #course_id, doc_id, doc_id_scrtyn, doc_id_scrtrmrk, doc_id_comment
FROM #DTProcessAdmittedDocUploadScrutiny;
/*Remaining Documents Insert into table*/
DELETE FROM tbl_ProcessAdmittedDocUploadScrutinyRemiaing WHERE stdfrm_id =#stdfrm_id
DECLARE #Id int,#doc_id int
WHILE (SELECT Count(*) FROM #sdtdoc_id) > 0
BEGIN
Select Top 1 #Id = n,#doc_id=id From #sdtdoc_id
--Do some processing here
insert into tbl_ProcessAdmittedDocUploadScrutinyRemiaing(stdfrm_id, doc_id )
values (#stdfrm_id,#doc_id)
insert into tbl_ProcessAdmittedDocUploadScrutinyRemiaingAuditLog
(scrtaudit_id, stdfrm_id, doc_id )
values (#scrtaudit_id,#stdfrm_id,#doc_id)
DELETE FROM #sdtdoc_id WHERE n = #Id
END --Begin end While
/*End Remaining Documents-----------*/
SET #result=#stdfrm_scrt_apprvstatus
END TRY
BEGIN CATCH
SET #result='N'
insert into tbl_ErrorSql( ErrorMessage, stdfrm_id)
values(coalesce(Error_Message(),ERROR_LINE()),#stdfrm_id)
END CATCH;
--End of Call Insert
END
SELECT #result
END

How to exec a stored procedure for each row in a select statement?

I have a stored procedure that returns an unique Id. I need to call this sp to get the unique ID for each row. I must use this SP because an application also uses this.
How can I select for each row a ID that is returned from the SP?
CREATE procedure [dbo].[SelectNextNumber]
#TableName nvarchar(255)
as
begin
declare #NewSeqVal int
set NOCOUNT ON
update Number --This is a table that holds for each table the max ID
set #NewSeqVal = Next = Next + Increase
where TableNaam= #TableName
if ##rowcount = 0
begin
Insert into Number VALUES (#TableName, 1, 1)
return 1
end
return #NewSeqVal
The number table:
CREATE TABLE [dbo].[Number](
[TableName] [varchar](25) NOT NULL,
[Next] [int] NULL,
[Increase] [int] NULL
I have seen that a While loop is usable for this but in my situation I don't know how to use a while loop.
You can't use stored procedures inside a SELECT statement, only functions.
You can iterate on a resultset with a cursor if you really have to use a stored procedure:
http://msdn.microsoft.com/library/ms180169.aspx
EDIT:
To be honest I'm not very sure to have understood what you really need, it looks like you are building a IDENTITY by yourself ( http://msdn.microsoft.com/library/ms174639(v=sql.105).aspx );
still, if you really need to run a cursor here's an example which uses your stored procedure:
http://sqlfiddle.com/#!3/2b81a/1
Taking the singular INSERT INTO.. SELECT apart:
Temporarily store the SELECT results away
declare #rc int, #NewSeqVal int;
SELECT ..
INTO #tmp -- add this
FROM ..
Store the rowcount and get that many numbers
set #rc = ##rowcount;
For which you have to use the code in the SP directly:
update Number --This is a table that holds for each table the max ID
set #NewSeqVal = Next = Next + #rc
where TableNaam= 'sometbl';
Finally, the insert
INSERT ...
SELECT ID = #NewSeqVal + 1 - row_number() over (ORDER BY col1)
, {all the other columns}
FROM #tmp;
ORDER by Col1 is arbitrary, choose something sensible, or make it ORDER BY NEWID() if you don't care.

How To Create a Custom Alphanumeric Primary key in Sql Server 2005

i write this alghorithm a and it's correct:
Tables were :
create table PrimKeyTest (primarykeycolumn varchar(8), nextcolumn int)
GO
insert into PrimKeyTest values ('P09-0001', 1)
GO
and My function is :
set ANSI_NULLS ON
set QUOTED_IDENTIFIER ON
GO
CREATE function [dbo].[GetSpecialPrimaryKey](#yearvalue int)
returns nvarchar(8)
as
begin
declare #maxkey varchar(4)
declare #maxLength int, #maxkeylength int
set #maxLength = 4
select #maxkey = ISNULL(cast(max(cast(substring(primaryKeycolumn, 5, 4) as integer)+1) as varchar),'1')
from PrimKeyTest
where substring(primaryKeycolumn, 2, 2) = substring(convert(varchar, #yearvalue), 3, 2)
set #maxkeylength = len(#maxkey)
while #maxkeylength < #maxLength
begin
set #maxkey = '0' + #maxkey
set #maxkeylength = len(#maxkey)
end
return 'P' + substring(convert(varchar, #yearvalue), 3, 2) + '-' + #maxkey
end
Now when i delete last row of this table ,new last record give correct number eg.
P09-0001 P09-0002 P09-0003 P09-0004 P09-0005
but when i delete 2nd row of this table order of primary column has incorrect
eg. P09-0001 P09-0003 P09-0004 P09-0005
can you help me?
i want this: P09-0001 P09-0002 P09-0003 P09-0004
This is actually not a great approach to dealing with primary keys. Doing this means "realigning" all of your pkeys whenever one is deleted (except when it's the last.) Doing this could be a complex, costly and error-prone process. For example, you have a pkey in this table which will probably be referenced via a foreign key from other tables. If you change the value of the pkey in the first table then you also have to change it in all the other tables that reference it. This means dropping any constraints for the duration of the change etc.
It looks like you're trying to create an identifier that will most likely be presented to the end user. You can go ahead and use your function to do that, BUT do not make it a primary key. Use an auto-incrementing column as the primary key and the 'P09-N' value as a separate field. Then, if you want to modify the values you can do so without affecting the rest of your table design.
Now to update the identifier values for the table whenever one is deleted you'll probably need to use a cursor in a stored procedure. Here's a good overview on cursors. You could also use CTEs (Common Table Expressions) to do the updating.
Here is a cursor example where Col1 is your pkey and Col2 is the identifier you want to change:
begin tran -- it's important to wrap this in a transaction!
declare #counter int
set #counter = 1
declare #val varchar(50)
DECLARE crs CURSOR
FOR SELECT Col1 FROM TblTest ORDER By Col1
OPEN crs
FETCH NEXT FROM crs INTO #val
WHILE ##FETCH_STATUS = 0
BEGIN
UPDATE TblTest
SET Col2 = 'P09-' + cast(#counter as varchar(50))
WHERE Col1 = #val
SET #counter = #counter + 1
FETCH NEXT FROM crs INTO #val
END
CLOSE crs
DEALLOCATE crs
commit tran
I didn't do the leading zero logic but you can Google for that pretty easily.

I need to run a stored procedure on multiple records

I need to run a stored procedure on a bunch of records. The code I have now iterates through the record stored in a temp table. The stored procedure returns a table of records.
I was wondering what I can do to avoid the iteration if anything.
set #counter = 1
set #empnum = null
set #lname = null
set #fname = null
-- get all punches for employees
while exists(select emp_num, lname, fname from #tt_employees where id = #counter)
begin
set #empnum = 0
select #empnum = emp_num, #lname = lname , #fname= fname from #tt_employees where id = #counter
INSERT #tt_hrs
exec PCT_GetEmpTimeSp
empnum
,#d_start_dt
,#d_end_dt
,#pMode = 0
,#pLunchMode = 3
,#pShowdetail = 0
,#pGetAll = 1
set #counter = #counter + 1
end
One way to avoid this kind of iteration is to analyze the code within the stored procedure and revised so that, rather than processing for one set of inputs at a time, it processes for all sets of inputs at a time. Often enough, this is not possible, which is why iteration loops are not all that uncommon.
A possible alternative is to use APPLY functionality (cross apply, outer apply). To do this, you'd rewrite the procedure as one of the table-type functions, and work that function into the query something like so:
INSERT #tt_hrs
select [columnList]
from #tt_employees
cross apply dbo.PCT_GetEmpTimeFunc(emp_num, #d_start_dt, #d_end_dt, 0, 3, 0, 1)
(It was not clear where all your inputs to the procedure were coming from.)
Note that you still are iterating over calls to the function, but now it's "packed" into one query.
I think you are on the right track.
you can have a temp table with identity column
CREATE TABLE #A (ID INT IDENTITY(1,1) NOT NULL, Name VARCHAR(50))
After records are inserted in to this temp table, find the total number of records in the table.
DECLARE #TableLength INTEGER
SELECT #TableLength = MAX(ID) FROM #A
DECLARE #Index INT
SET #Index = 1
WHILE (#Index <=#TableLength)
BEGIN
-- DO your work here
SET #Index = #Index + 1
END
Similar to what you have already proposed.
Alternative to iterate over records is to use CURSOR. CURSORS should be avoided at any cost.