create procedure test
(#TABLE_NAME varchar(20))
as
declare #lastval varchar(10)
set #lastval = right('000000000' + convert(varchar(10),
(select IsNull(max(Serialno), 0) + 1
from #TABLE_NAME)), 10)
return #lastval
end
Now tell me how I could compose or form dynamic SQL with above SQL where I will pass table name to store procedure when call that stored procedure?
How to return #lastval value to its calling environment?
How to call stored procedure test from another stored procedure where I will store the return value ?
Guide me with sample code.
Genearlly, it's best to use an IDENTITY or a SEQUENCE to assign serial numbers. A zero-padded string or other formatting requirements could be added to the table as a computed column based on the underlying serial integer or formatted in the app code. However, both IDENTITY and SEQUENCE may have gaps, such as due to rollbacks or SQL Server service restart.
In cases where an unbroken sequence of serial values is required by business, one can maintan the last assigned values in a table and assign values transactionally. Below is an example that returns the value using an OUTPUT parameter. Although the proc in your question uses the stored proc RETURN value for this purpose, that should only be used to indicate success or failure, not return data.
CREATE TABLE dbo.TableSerialNumber(
TableName sysname NOT NULL
CONSTRAINT PK_SerialNumber PRIMARY KEY
, SerialNumber int NOT NULL
, FormatString nvarchar(20) NULL
);
GO
INSERT INTO dbo.TableSerialNumber VALUES('Invoice', 0, '0000000000');
INSERT INTO dbo.TableSerialNumber VALUES('PurchaseOrder', 0, '0000000000');
GO
CREATE PROC dbo.GetNextSerialNumberForTable
#TableName sysname
, #FormattedSerialNumber varchar(10) OUTPUT
AS
SET NOCOUNT ON;
DECLARE
#SerialNumber int
, #FormatString nvarchar(20);
UPDATE dbo.TableSerialNumber
SET
#SerialNumber = SerialNumber += 1
, #FormatString = FormatString
WHERE TableName = #TableName;
IF ##ROWCOUNT = 0
RAISERROR('Table %s does not exist in dbo.TableSerialNumber', 16, 1, #TableName);
SET #FormattedSerialNumber = CAST(FORMAT(#SerialNumber, #FormatString) AS varchar(10));
GO
--example usage
CREATE PROC dbo.InsertInvoice
#InvoiceData int
AS
SET XACT_ABORT ON;
DECLARE #InvoiceNumber varchar(10);
BEGIN TRY
BEGIN TRAN;
EXECUTE dbo.GetNextSerialNumberForTable
#TableName = N'Invoice'
, #FormattedSerialNumber = #InvoiceNumber OUTPUT;
INSERT INTO dbo.Invoice (InvoiceID, InvoiceData)
VALUES(#InvoiceNumber, #InvoiceData);
SELECT #InvoiceNumber AS InvoiceNumber;
COMMIT;
END TRY
BEGIN CATCH
IF ##TRANCOUNT > 0 ROLLBACK;
THROW;
END CATCH;
GO
I am getting the below error while executing a stored procedure
USE [Smart2uat]
GO
/****** Object: StoredProcedure [dbo].[SPJOB_ALLLOC] Script Date: 2/11/2016 12:37:40 PM ******/
SET ANSI_NULLS OFF
GO
SET QUOTED_IDENTIFIER OFF
GO
ALTER PROCEDURE [dbo].[SPJOB_ALLLOC] AS
declare #cardno as varchar(8)
declare #iodate as datetime
declare #iotime as varchar(8)
declare #holdername as varchar(100)
declare #IO_MSKID as varchar(7)
declare #IO_LOCATION_CODE as varchar(3)
declare #IO_COMPANY_CODE as varchar(3)
declare #IO_ACTIVITY_CODE as varchar(6)
declare #IO_FIRST_NAME as varchar(20)
declare #IO_THIRD_NAME as varchar(20)
declare #IO_EMPLOYEE_CODE as varchar(3)
declare #rows as integer
declare curatt1 cursor for
select iodate,cardno,iotime,holdername from iodatatmp where isnull(cardno,'')<>'' and isnull(cardno,'') not like 'XXXX%' order by iotime
open curatt1
fetch next from curatt1 into #iodate,#cardno,#iotime,#holdername
WHILE ##FETCH_STATUS = 0
BEGIN
if not exists(select CardNo from iodata where iodate= #iodate and cardno= #cardno)
begin
select #IO_MSKID = ''
select #IO_MSKID=MSKID,#IO_LOCATION_CODE=LOCATION_CODE,#IO_COMPANY_CODE=COMPANY_CODE,#IO_ACTIVITY_CODE=ACTIVITY_CODE,#IO_FIRST_NAME=FIRST_NAME,#IO_THIRD_NAME=THIRD_NAME,#IO_EMPLOYEE_CODE=EMPLOYEE_CODE from Employee_Mast where card_number = #cardno
IF #IO_MSKID <> ''
insert into iodata(cardno,iodate,iotime,holdername,IO_MSKID,IO_LOCATION_CODE,IO_COMPANY_CODE,IO_ACTIVITY_CODE,IO_FIRST_NAME,IO_THIRD_NAME,IO_EMPLOYEE_CODE)
values(#cardno,#iodate,#iotime,#holdername,#IO_MSKID,#IO_LOCATION_CODE,#IO_COMPANY_CODE,#IO_ACTIVITY_CODE,#IO_FIRST_NAME,#IO_THIRD_NAME,#IO_EMPLOYEE_CODE)
end
fetch next from curatt1 into #iodate,#cardno,#iotime,#holdername
END
close curatt1
deallocate curatt1
delete from iodata where cardno like 'XXXX%'
error is
Msg 8152, Level 16, State 14, Procedure SPJOB_ALLLOC, Line 31
String or binary data would be truncated.
The statement has been terminated.
(0 row(s) affected)
Can you please help me..? I am attaching the table design of iodatatmp on which the cursor is fetching and the destination table - Iodata
I have checked the length of the variable...and seems everything fine....Kindly help me..Thanks in advance
The error you are getting is caused by the fact that the size of some of the varchar type columns in IODataTmp are larger than the equivalent column in IOData.
For instance IODataTmp.Holdername is declared as varchar(32) and yet IOData.Holdername is declared as varchar(20) and so if you have a value in IODataTmp.Holdername that is longer than 20 characters it will fail when it tries to insert into IOData.Holdername. Another issue you have is that variables you have declared in the stored procedure to hold the values are a different size again, #holdername is declared as varchar(100).
The solution is to ensure that all the column and variable sizes for a piece of data are the same.
i am exporting some date to sql server using string builder.and here i assign all the values to particular tables.but i don't know i got some error.i can't resolve.help me to resolve this.
ALTER PROCEDURE [dbo].[usp_CreateEmployeDetails]
#nEmployeeDetailsInXML nvarchar(max)=''
As
DECLARE #iTree INTEGER
declare #empid int
BEGIN
SET NOCOUNT ON;
create table #TempRelation(RowNo int identity(1,1),RelationShipId int,RelativeName nvarchar(100),DOB date,IsNominee bit)
create table #Temp_Present_Address(RowNo int identity(1,1),Street1 nvarchar(200),Street2 nvarchar(200),CountryId int,StateId int,CityId int,AddressTypeId int)
create table #Temp_Permanent_Address(RowNo int identity(1,1),Street1 nvarchar(200),Street2 nvarchar(200),CountryId int,StateId int,CityId int,AddressTypeId int)
create table #TempDetails(RowNo int identity(1,1),EmployeeName nvarchar(100),DOB date,DOJ date,Email nvarchar(100),Phone bigint,BoodGroup nchar(10),
PAN_No nvarchar(15),PF_No nvarchar(100),Sex char(10),AccountNo nvarchar(100),BankName nvarchar(100),BranchId int,ManagerId int,HrId int,DesigId int)
exec sp_xml_preparedocument #iTree output,#nEmployeeDetailsInXML
insert into #TempRelation(RelationShipId,RelativeName,DOB,IsNominee)
select RelationShipId,RelativeName,DOB,IsNominee
from openxml (#iTree,'EmployeeDetails/EmployeeRelation',1)
with(RelationShipId int,RelativeName nvarchar(100),DOB date,IsNominee bit)
insert into #Temp_Permanent_Address(Street1,Street2,CountryId,StateId,CityId,AddressTypeId)
select Street1,Street2,CountryId,StateId,CityId,AddressTypeId
from openxml (#iTree,'EmployeeDetails/EmployeePermanentAdress',1)
with(Street1 nvarchar(200),Street2 nvarchar(200),CountryId int,StateId int,CityId int,AddressTypeId int)
insert into #Temp_Present_Address(Street1,Street2,CountryId,StateId,CityId,AddressTypeId)
select Street1,Street2,CountryId,StateId,CityId,AddressTypeId
from openxml (#iTree,'EmployeeDetails/EmployeePresentAdress',1)
with(Street1 nvarchar(200),Street2 nvarchar(200),CountryId int,StateId int,CityId int,AddressTypeId int)
insert into #TempDetails(EmployeeName,DOB,DOJ,Email,Phone,BoodGroup,PAN_No,PF_No,Sex,AccountNo,BankName,BranchId,ManagerId,HrId,DesigId)
select EmployeeName,DOB,DOJ,Email,Phone,BoodGroup,PAN_No,PF_No,Sex,AccountNo,BankName,BranchId,ManagerId,HrId,DesigId
from openxml (#iTree,'EmployeeDetails/Employee',1)
with(EmployeeName nvarchar(100),DOB date,DOJ date,Email nvarchar(100),Phone bigint,BoodGroup nchar(10),PAN_No nvarchar(15),PF_No nvarchar(100),Sex char(10),
AccountNo nvarchar(100),BankName nvarchar(100),BranchId int,ManagerId int,HrId int,DesigId int)
if((select COUNT(RowNo) from #TempDetails)>0)
begin
insert into Employee(EmployeeName,DOB,DOJ,Email,Phone,BoodGroup,PAN_No,PF_No,Sex)output inserted.EmployeeId select EmployeeName,DOB,DOJ,Email,Phone,BoodGroup,PAN_No,PF_No,Sex from #TempDetails
set #empid=SCOPE_IDENTITY()
if((select COUNT(EmployeeName) from Employee where EmployeeId=#empid)>0)
begin
insert into EmployeeAccountDetls(EmployeeId,AccountNo,BankName)values(#empid,(select AccountNo,BankName from #TempDetails))
insert into EmployeeLink(EmployeeId,BranchId,ManagerId,HrId,DesigId)values(#empid,(select BranchId,ManagerId,HrId,DesigId from #TempDetails))
if((select COUNT(RowNo) from #Temp_Permanent_Address)>0)
begin
insert into EmployeeAddress(EmployeeId,Street1,Street2,CountryId,StateId,CityId,AddressTypeId)values(#empid,(select Street1,Street2,CountryId,StateId,CityId,AddressTypeId from #Temp_Permanent_Address))
end
if((select COUNT(RowNo) from #Temp_Present_Address)>0)
begin
insert into EmployeeAddress(EmployeeId,Street1,Street2,CountryId,StateId,CityId,AddressTypeId)values(#empid,(select Street1,Street2,CountryId,StateId,CityId,AddressTypeId from #Temp_Present_Address))
end
if((select COUNT(RowNo) from #TempRelation)>0)
begin
insert into EmployeeRelationDetls(EmployeeId,RelationShipId,RelativeName,DOB,isNominee)values(#empid,(select RelationShipId,RelativeName,DOB,IsNominee from #TempRelation))
end
end
end
EXEC sp_xml_removedocument #iTree
drop table #Temp_Present_Address
drop table #Temp_Permanent_Address
drop table #TempDetails
drop table #TempRelation
END
why its happening i checked but i didn't get the result
For the specific error you mention, your problem is here:
insert into EmployeeAddress(EmployeeId,Street1,Street2,CountryId,StateId,CityId,AddressTypeId)
values (#empid, (select Street1,Street2,CountryId,StateId,CityId,AddressTypeId from #Temp_Permanent_Address))
You probably want:
insert into EmployeeAddress(EmployeeId,Street1,Street2,CountryId,StateId,CityId,AddressTypeId)
SELECT #empid,Street1,Street2,CountryId,StateId,CityId,AddressTypeId from #Temp_Permanent_Address
However, you're inserting multiple rows and then giving the last rows IDENTITY value to every address row doing that. You need to find a better way of relating keys - which can either be done using MERGE's output clause or by using a stronger key to reference back to the table you just inserted into in order to find the newly inserted employee ID.