SQL call a SP from another SP - sql

Can I please have some help with the syntax of a SP in SQL.
Here is my code:
CREATE PROCEDURE usp_GetValue
(
#ID VARCHAR(10),
#Description VARCHAR(10)
)
AS
BEGIN
return #ID + #Description
END
CREATE PROCEDURE usp_InsertValue
(
#ID VARCHAR(10),
#FirstName VARCHAR(50),
#LastName VARCHAR(50),
#Description VARCHAR(10),
#Comment VARCHAR(max)
)
AS
BEGIN
Declare #v_Value VARCHAR(15)
Set #v_Value = usp_GetValue(#ID, #Description)
END
In the usp_InsertValue SP, I am wanting to declare and set a variable. Once the variable has been declared, I then wish to call another SP with parameters to set the value of the declared variable.
I am not sure of the syntax. May I please have some help?
UPDATE
I have updated my above code using your function. How do I Set the #v_Value from the usp_GetValue function.
I am getting this error:
'usp_GetValue' is not a recognized built-in function name.
UPDATE2
Here is my full code:
CREATE PROCEDURE usp_PersonCategoryLookupTesting
(
#ID VARCHAR(10),
#Description VARCHAR(10),
#res VARCHAR(10) OUTPUT
)
AS
BEGIN
return #ID + #Description
END
CREATE PROCEDURE usp_InsertPersonTesting
(
#IDTest VARCHAR(10),
#FirstName VARCHAR(50),
#LastName VARCHAR(50),
#AddressLine1 VARCHAR(50),
#AddressLine2 VARCHAR(50),
#AddressLine3 VARCHAR(50),
#MobilePhone VARCHAR(20),
#HomePhone VARCHAR(20),
#Description VARCHAR(10),
#Comment VARCHAR(max)
)
AS
BEGIN
Declare #PersonCategory VARCHAR(15)
EXEC usp_PersonCategoryLookupTest #ID, #Description, #PersonCategory
INSERT INTO Person(FirstName, LastName, AddressLine1, AddressLine2, AddressLine3, MobilePhone, HomePhone, DateModified, PersonCategory, Comment)
VALUES (#FirstName, #LastName, #AddressLine1, #AddressLine2, #AddressLine3, #MobilePhone, #HomePhone, GETDATE (), #PersonCategory, #Comment)
END
I am getting this error in my application that is calling the SQL code:
Conversion failed when converting the varchar value '123Client' to data type int.
I am using the values "123" and "Client" for #IDTest and #Description.

I think output parameters should be the proper way:
See this post:
stored procedure returns varchar
CREATE PROCEDURE usp_GetValue
(
#ID VARCHAR(10),
#Description VARCHAR(10),
#res VARCHAR(10) OUTPUT
)
AS
BEGIN
return #ID + #Description
END
CREATE PROCEDURE usp_InsertValue
(
#ID VARCHAR(10),
#FirstName VARCHAR(50),
#LastName VARCHAR(50),
#Description VARCHAR(10),
#Comment VARCHAR(max)
)
AS
BEGIN
Declare #v_Value VARCHAR(15)
EXEC usp_GetValue #ID, #Description, #v_Value
-- use #v_Value here...
END

You can only use a function like that, not stored procedure. Stored Procedures only return integer values.
For SP, you need to create out parameters to retrieve the values. For this scenario, it is better to create a function
CREATE FUNCTION usp_GetValue
(
#ID VARCHAR(10),
#Description VARCHAR(10),
)
RETURNS VARCHAR(50)
AS
BEGIN
return #ID + #Description
END
Then call it:
SET #v_value = dbo.usp_GetValue('John','Doe') --output: John Doe
If you insist you want a SP, which is not proper for this, there are 2 ways
1) An out parameter
CREATE PROCEDURE usp_GetValue
(
#ID VARCHAR(10),
#Description VARCHAR(10),
#Result varchar(20) OUTPUT
)
AS
BEGIN
SET #Result = #ID + #Description
END
Then call it:
Declare #v_Value VARCHAR(15)
Set #v_Value = EXEC usp_GetValue #ID, #Description, #v_Value OUTPUT
2) Select from it
CREATE PROCEDURE usp_GetValue
(
#ID VARCHAR(10),
#Description VARCHAR(10)
)
AS
BEGIN
SELECT #ID + #Description
END
Use it like this:
declare #tempresult as table(v_value as varchar(15))
INSERT INTO #tempresult
EXEC usp_GetValue #ID, #Description
Select Top 1 #v_value = v_value From #tempresult
My advise is use the function approach.

Related

Transaction count after EXECUTE indicates mismatching number of BEGIN and COMMIT statements

When I execute the below stored procedure I get this error:
System.Data.SqlClient.SqlException: Transaction count after EXECUTE
indicates a mismatching number of BEGIN and COMMIT statements.
Previous count = 0, current count = 1.
Code:
create procedure [dbo].[sp_crm_diler_master]
(
#Fullname varchar(100),
#Email varchar(50),
#Mobile varchar(12),
#qualification varchar(50),
#presentaddress varchar(250),
#permanentaddress varchar(250),
#location varchar(50),
#skills varchar(100),
#Dob varchar(15),
#myphoto varbinary(Max),
#uniqueid varchar(25),
#Message varchar(150) output
)
AS
BEGIN
if not exists (select emailid,phone from crm_masterdata where emailid=#Email And phone=#Mobile)
begin
begin transaction
declare #small smalldatetime = (select CAST(#Dob as smalldatetime))
declare #todaydate datetime=(select getdate())
insert into crm_masterdata(uniqueid,fullname,phone,dob,photo,emailid,qualification,location,present_address,permanent_address,skillsets,datasource,entrydate,active)
values(#uniqueid,#Fullname,#Mobile,#small,#myphoto,#Email,#qualification,#location,#presentaddress,#permanentaddress,#skills,'reception',#todaydate,1)
Set #Message=' Registration Successfull,Please Login'
end
else
begin
set #Message='This User Already Registered'
end
end
Where is my error?
create procedure [dbo].[sp_crm_diler_master]
(
#Fullname varchar(100),
#Email varchar(50),
#Mobile varchar(12),
#qualification varchar(50),
#presentaddress varchar(250),
#permanentaddress varchar(250),
#location varchar(50),
#skills varchar(100),
#Dob varchar(15),
#myphoto varbinary(Max),
#uniqueid varchar(25),
#Message varchar(150) output
)
AS
BEGIN
SET NOCOUNT ON;
declare #small smalldatetime = (select CAST(#Dob as smalldatetime));
declare #todaydate datetime=getdate();
declare #Error INT;
BEGIN TRANSACTION; --<-- You need to commit it
IF not exists (select 1 from crm_masterdata where emailid=#Email And phone=#Mobile)
BEGIN
insert into crm_masterdata(uniqueid,fullname,phone,dob,photo,emailid
,qualification,location,present_address,permanent_address,skillsets,datasource,entrydate,active)
values(#uniqueid,#Fullname,#Mobile,#small,#myphoto,#Email,#qualification
,#location,#presentaddress,#permanentaddress,#skills,'reception',#todaydate,1)
SET #Error = ##ERROR;
Set #Message =' Registration Successfull,Please Login'
END
ELSE
BEGIN
SET #Message='This User Already Registered'
END
IF (#Error = 0)
COMMIT TRANSACTION; --<-- Commit tran
ELSE
ROLLBACK TRANSACTION;
END
I don't see a COMMIT TRANSACTION to match your BEGIN TRANSACTION.

SQL Server : Dynamic Query in Stored Procedure in

I tried to write dynamic query in SQL Server. However I get warning like below,
The Selected stored procedure or function returns no columns
I have been trying to achieve this however it still does not run.
Where did I miss ?
ALTER PROCEDURE [dbo].[S_ProjeGetir1]
#ID int=0,
#AktifMi int,
#ProjeFirma int,
#Icinde int,
#AramaText Varchar(500),
#Arasinda1 Varchar(50),
#Arasinda2 Varchar(50)
AS
BEGIN
Create Table #TempTable
(Sonuc int
,ID int
,FirmaID int
,PrismProjeID int
,ProjeAdi nvarchar(150)
,RgID uniqueidentifier
,HaritaEnlem nvarchar(25)
,HaritaBoylam nvarchar(25)
,ProjeTeslimTarihi datetime
,HemenTeslimMi bit
,Adres nvarchar(250)
,AdresUlkeID int
,AdresILID int
,AdresILceID int
,AdresSemtID int
,KonutSayisi int
,LansmanTarihi datetime
,OfisSayisi int
,MagazaSayisi int
,BlokSayisi int
,YesilAlan int
,KrediyeUygunMu bit
,AktifMi bit
,UcBoyutVarMi bit
,UlkeAdi nvarchar(150)
,Sehir nvarchar(50)
,Ilce nvarchar(50)
,Semt nvarchar(50)
,FirmaAdi nvarchar(100)
,StokSonGuncellemeTarihi datetime)
Declare #SqlText varchar(8000),
#AktifPasif bit
Set #AktifPasif=Case When #AktifMi=0 Then 1 When #AktifMi=1 Then 0 End
SET NOCOUNT ON
BEGIN TRY
Set #SqlText=' SELECT 1 Sonuc ,[ID],[FirmaID] ,[PrismProjeID],[ProjeAdi] ,[RgID] ,[HaritaEnlem] ,[HaritaBoylam] ,[ProjeTeslimTarihi]
,[HemenTeslimMi],[Adres] ,[AdresUlkeID] ,[AdresILID] ,[AdresILceID] ,[AdresSemtID] ,[KonutSayisi]
,[LansmanTarihi],[OfisSayisi] ,[MagazaSayisi],[BlokSayisi],[YesilAlan] ,[KrediyeUygunMu],[AktifMi]
,[UcBoyutVarMi] ,[UlkeAdi] ,[Sehir] ,[Ilce] ,[Semt]
,[FirmaAdi] ,[StokSonGuncellemeTarihi]
FROM [dbo].[V_Proje] AS P WITH (NOLOCK)
WHERE 1=1 '
If #ID>0 Set --ID ye Göre İlgili Kayıdı almak için
#SqlText=#SqlText +' and ID=' +cast(#ID as Varchar(50))
Else
Begin
--Aktif ise veya Pasif ise
if #AktifMi=0 or #AktifMi=1
Begin
Set #SqlText=#SqlText +' and AktifMi='+cast(#AktifPasif as varchar(50))
End
--Bütün Alanları sorgulamak için
Set #SqlText=#SqlText +' and CASE WHEN '+cast(#ProjeFirma as varchar(50))+'=1 THEN Upper(ProjeAdi)
WHEN '+cast(#ProjeFirma as varchar(50))+'=0 THEN Upper(FirmaAdi)
WHEN '+cast(#ProjeFirma as varchar(50))+'=2 THEN Upper(HaritaEnlem)
WHEN '+cast(#ProjeFirma as varchar(50))+'=3 THEN Upper(HaritaBoylam)
WHEN '+cast(#ProjeFirma as varchar(50))+'=4 THEN Upper(Adres)'
If #Icinde=0--İçinde
Set #SqlText=#SqlText +' END Like ''%'+#AramaText+'%'' '
If #Icinde=1--İle Başlayan
Set #SqlText=#SqlText +' END Like '''+#AramaText+'%'' '
If #Icinde=2--Arasında
Set #SqlText=#SqlText +' END between '''+ #Arasinda1+''' and '''+#Arasinda2+''''
--select #SQLTEXT
End
exec('insert into #TempTable ' + #SqlText)
Select Sonuc, [ID],[FirmaID],[PrismProjeID],[ProjeAdi] ,[RgID] ,[HaritaEnlem],[HaritaBoylam],[ProjeTeslimTarihi],[HemenTeslimMi]
,[Adres] ,[AdresUlkeID] ,[AdresILID],[AdresILceID] ,[AdresSemtID],[KonutSayisi] ,[LansmanTarihi] ,[OfisSayisi]
,[MagazaSayisi],[BlokSayisi] ,[YesilAlan],[KrediyeUygunMu],[AktifMi] ,[UcBoyutVarMi],[UlkeAdi],[Sehir] ,[Ilce],[Semt]
,[FirmaAdi] ,[StokSonGuncellemeTarihi]
From #TempTable AS T WITH (NOLOCK)
END TRY
BEGIN CATCH
SELECT -1 AS Sonuc -- EXCEPTION
END CATCH
SET NOCOUNT OFF
END
Any help will be appreciated.
Thanks
I am not sure if what i am going to tell is going to work for EF, but i had a similar case in LINQ to SQL classes.
Backup the code of your Stored Procedure
Create a single SELECT statement with appropriate values, in your Stored Procedure like the following:
ALTER PROCEDURE [dbo].[S_ProjeGetir1]
#ID int=0,
#AktifMi int,
#ProjeFirma int,
#Icinde int,
#AramaText Varchar(500),
#Arasinda1 Varchar(50),
#Arasinda2 Varchar(50)
AS
BEGIN
Select CONVERT(VARCHAR(30),'') AS Sonuc, -- Make sure to convert to what your
0 AS [ID],
0 AS [FirmaID],
0 AS [PrismProjeID],
...
END
Import this Stored Procedure in EF
If all goes well, restore the backed up code in the Stored Procedure.

execute stored procedure based on condition

i tried to insert data in database using stored procedure but according to some condition. for example if data is already exists in database the the stored procedure should not be executed.
i am doing the following code but it return 0 every time rather then i want. What can i do
ALTER PROCEDURE dbo.SaveUser
(
#cid int,
#firstname varchar(20),
#lastname varchar(20),
#dob datetime,
#gender varchar(20),
#add varchar(100),
#email varchar(40),
#quali varchar(20),
#yop varchar(15),
#exp varchar(10),
#pass varchar(20)
)
AS
declare #result int
if EXISTS( select Email_ID from Registration where Email_ID=#email )
begin
set #result=4;
return #result;
end
else
begin
insert into Registration values(#cid, #firstname, #lastname, #dob, #gender, #add, #email, #quali, #yop, #exp, #pass );
set #result =0;
return #result;
end
You can simply proceed as follows;
ALTER PROCEDURE dbo.SaveUser
(
#cid int,
#firstname varchar(20),
#lastname varchar(20),
#dob datetime,
#gender varchar(20),
#add varchar(100),
#email varchar(40),
#quali varchar(20),
#yop varchar(15),
#exp varchar(10),
#pass varchar(20)
)
AS
BEGIN
DECLARE #return int
if NOT EXISTS(select Email_ID from Registration where Email_ID=#email)
insert into Registration values(#cid, #firstname, #lastname,
#dob, #gender, #add, #email,
#quali, #yop, #exp, #pass )
If (##ERROR <> 0)
Begin
Set #return = 4
Else
Set #return = 0
End
Return #return
END
You can use raiseerror event for this scenario
if EXISTS( select Email_ID from Registration where Email_ID=#email )
begin
RAISERROR(N'Email id already exist.', 10, 2,'')
end
Here 10 is severity level and according to severity level sql server identified as info meassage or exception. For more information
RaiseError
Database Engine Severity Levels
Try this one -
ALTER PROCEDURE dbo.SaveUser
(
#cid INT,
#firstname VARCHAR(20),
#lastname VARCHAR(20),
#dob DATETIME,
#gender VARCHAR(20),
#add VARCHAR(100),
#email VARCHAR(40),
#quali VARCHAR(20),
#yop VARCHAR(15),
#exp VARCHAR(10),
#pass VARCHAR(20)
)
AS BEGIN
IF NOT EXISTS(
SELECT 1
FROM dbo.Registration
WHERE Email_ID = #email
) BEGIN
INSERT INTO dbo.Registration
SELECT #cid, #firstname, #lastname, #dob, #gender, #add, #email, #quali, #yop, #exp, #pass
RETURN 0;
END
RETURN 4;
END

How can I iterate over a recordset within a stored procedure?

I need to iterate over a recordset from a stored procedure and execute another stored procedure using each fields as arguments. I can't complete this iteration in the code. I have found samples on the internets, but they all seem to deal with a counter. I'm not sure if my problem involved a counter. I need the T-SQL equivalent of a foreach
Currently, my first stored procedure stores its recordset in a temp table, #mytemp. I assume I will call the secondary stored procedure like this:
while (something)
execute nameofstoredprocedure arg1, arg2, arg3
end
You need to create a cursor to loop through the record set.
Example Table:
CREATE TABLE Customers
(
CustomerId INT NOT NULL PRIMARY KEY IDENTITY(1,1)
,FirstName Varchar(50)
,LastName VARCHAR(40)
)
INSERT INTO Customers VALUES('jane', 'doe')
INSERT INTO Customers VALUES('bob', 'smith')
Cursor:
DECLARE #CustomerId INT, #FirstName VARCHAR(30), #LastName VARCHAR(50)
DECLARE #MessageOutput VARCHAR(100)
DECLARE Customer_Cursor CURSOR FOR
SELECT CustomerId, FirstName, LastName FROM Customers
OPEN Customer_Cursor
FETCH NEXT FROM Customer_Cursor INTO
#CustomerId, #FirstName, #LastName
WHILE ##FETCH_STATUS = 0
BEGIN
SET #MessageOutput = #FirstName + ' ' + #LastName
RAISERROR(#MessageOutput,0,1) WITH NOWAIT
FETCH NEXT FROM Customer_Cursor INTO
#CustomerId, #FirstName, #LastName
END
CLOSE Customer_Cursor
DEALLOCATE Customer_Cursor
Here is a link to MSDN on how to create them.
http://msdn.microsoft.com/en-us/library/ms180169.aspx
This is why I used Raise Error instead of PRINT for output.
http://structuredsight.com/2014/11/24/wait-wait-dont-tell-me-on-second-thought/
It's very easy to loop through the rows in SQL procedure. You just need to use a cursor. Here is an example:
Let us consider a table Employee with column NAME and AGE with 50 records into it and you have to execute a stored procedure say TESTPROC which will take name and age parameters of each row.
create procedure CursorProc
as
begin
declare #count bigint;
declare #age varchar(500)
declare #name varchar(500)
select #count = (select count(*) from employee)
declare FirstCursor cursor for select name, age from employee
open FirstCursor
while #count > 0
begin
fetch FirstCursor into #name, #age
Exec TestProc #name, #age
set #count = #count - 1
end
close FirstCursor
deallocate FirstCursor
end
Make sure you deallocate the cursor to avoid errors.
try this (cursor free looping):
CREATE TABLE #Results (RowID int identity(1,1), Col1 varchar(5), Col2 int, ... )
DECLARE #Current int
,#End int
DECLARE #Col1 varchar(5)
,#Col2 int
,...
--you need to capture the result set from the primary stored procedure
INSERT INTO #Results
(Col1, COl2,...)
EXEC nameofstoredprocedure_1 arg1, arg2, arg3
SELECT #End=##ROWCOUNT,#Current=0
--process each row in the result set
WHILE #Current<#End
BEGIN
SET #Current=#Current+1
SELECT
#Col1=COl1, #Col2=Col2
FROM #Results
WHERE RowID=#Current
--call the secondary procedure for each row
EXEC nameofstoredprocedure_2 #Col1, #Col2,...
END
working example:
CREATE PROCEDURE nameofstoredprocedure_1
(#arg1 int, #arg2 int, #arg3 int)
AS
SELECT 'AAA',#arg1 UNION SELECT 'BBB',#arg2 UNION SELECT 'CCC',#arg3
GO
CREATE PROCEDURE nameofstoredprocedure_2
(#P1 varchar(5), #P2 int)
AS
PRINT '>>'+ISNULL(#P1,'')+','+ISNULL(CONVERT(varchar(10),#P2),'')
GO
CREATE TABLE #Results (RowID int identity(1,1), Col1 varchar(5), Col2 int)
DECLARE #Current int
,#End int
DECLARE #Col1 varchar(5)
,#Col2 int
INSERT INTO #Results
(Col1, COl2)
EXEC nameofstoredprocedure_1 111, 222, 333
SELECT #End=##ROWCOUNT,#Current=0
WHILE #Current<#End
BEGIN
SET #Current=#Current+1
SELECT
#Col1=COl1, #Col2=Col2
FROM #Results
WHERE RowID=#Current
EXEC nameofstoredprocedure_2 #Col1, #Col2
END
OUTPUT:
(3 row(s) affected)
>>AAA,111
>>BBB,222
>>CCC,333

SQL Server: Return uniqueidentifier from stored procedure

Can I return UNIQUEIDENTIFIER from a stored procedure using the RETURN statement or is it only by using the OUTPUT statement?
i.e to return the PersonID UNIQUEIDENTIFIER:
CREATE PROCEDURE CreatePerson
#Name NVARCHAR(255),
#Desc TEXT
AS
DECLARE #Count INT
DECLARE #JobFileGUID UNIQUEIDENTIFIER
-- Check if job exists?
SET #Count = (SELECT COUNT(Name) AS Name FROM Person WHERE Name=#Name)
IF #Count < 1
BEGIN
SET #PersonGUID = NEWID();
INSERT INTO Person
(PersonID, Name, [Desc])
VALUES (#PersonGUID, #Name, #Desc)
END
SELECT #PersonGUID = Person.PersonID
FROM Person
WHERE Name = #Name
RETURN #PersonGUID
GO
Thanks
In stored procedure - only using the OUTPUT statement. In function - return.
Use:
CREATE PROCEDURE CreatePerson
#Name NVARCHAR(255),
#Desc TEXT,
#PersonGUID UNIQUEIDENTIFIER OUTPUT
AS
BEGIN
SET #PersonGUID = ...
END
How to call:
DECLARE
#name NVARCHAR(255),
#desc TEXT,
#personGUID UNIQUEIDENTIFIER
SET #name = 'Bob'
SET #desc = 'One handsome man.'
EXEC [Database].[schema].CreatePerson #name, #desc, #personGUID OUTPUT
From the documentation you can actually see that a return in a stored procedure is actually used as a response code, hence you get the exception when trying to return a uniqueidentifier.
https://learn.microsoft.com/en-us/sql/relational-databases/stored-procedures/return-data-from-a-stored-procedure?view=sql-server-ver16#return-data-using-a-return-code
How I solved it, is by just performing a SELECT after the insert of the generated unique identifier.
DECLARE #ReportId UNIQUEIDENTIFIER;
SET #ReportId = NEWID();
INSERT INTO [dbo].[Report]
([ReportId]
,[ReportName])
VALUES
(#ReportId
,#ReportName)
SELECT #ReportId as ReportIdInternal
You'll have to see how to perform that with multiple selects though.
CREATE TABLE [dbo].[tbl_Clients]( [ClientID] [uniqueidentifier] NULL, [ClientName] varchar NULL, [ClientEnabled] [bit] NULL ) ON [PRIMARY]
GO
CREATE PROCEDURE [dbo].[sp_ClientCreate] #in_ClientName varchar(250) = "New Client 123", #in_ClientEnabled bit, #out_ClientId uniqueidentifier OUTPUT AS
SET #out_ClientId = NEWID();
INSERT INTO tbl_Clients(ClientId, ClientName, ClientEnabled) VALUES( #out_ClientId, #in_ClientName, #in_ClientEnabled)
DECLARE #return_value int, #out_ClientId uniqueidentifier
EXEC #return_value = [dbo].[sp_ClientCreate] #in_ClientName = N'111', #in_ClientEnabled = 1, #out_ClientId = #out_ClientId OUTPUT
SELECT #out_ClientId as N'#out_ClientId'
SELECT 'Return Value' = #return_value
GO
Result:-59A6D7FE-8C9A-4ED3-8FC6-31A989CCC8DB