SQL with input condition - sql

I have a customer table-firstname,lastname,gender,salary. I am creating a stored procedure with 5 input parameters: #FN, #LN, #GNDR, #SLRY and #TYPE.
Now, if #type=0 and #FN='SAM' - then,
it should insert a new record in the table, if 'SAM' is already existing in the table.
if #type=1 and #FN='SAM' - then,
it should delete a record from the table, if 'SAM' is already existing in the table.
if #type=2 and #FN='SAM' - then,
it should update a record in the table if 'SAM' is already existing in the table.
Please help me in creating a query for the above condition.

Please check by solution .
Please create different case in SQL Server .
CREATE PROCEDURE Insertcustomer (
#FN VARCHAR(30),
#LN VARCHAR(30),
#GNDR VARCHAR(30),
#SLRY DECIMAL(18,3) ,
#TYPE INT )
As
BEGIN
IF #type=0 AND #FN='SAM'
BEGIN
Insert into customer(firstname,lastname,gender,salary)values(#FN,
#LN,#GNDR,#SLRY,#TYPE)
END
IF #type=1 AND #FN='SAM'
BEGIN
Delete from customer where firstname= #FN
END
IF #type=2 AND #FN='SAM'
BEGIN
update customer set
firstname=#FN,lastname=#LN,gender=#GNDR,salary=#SLRY where
firstname= #FN
END
END
It will be work for you .
Thanks .

This elaborates on JaydibJ's PROC
CREATE PROCEDURE ProcedureName (#FN VARCHAR(30), #LN VARCHAR(30), #GNDR VARCHAR(30), #SLRY DECIMAL(18,3) , #TYPE INT )
As
BEGIN
IF #FN = 'SAM' AND (SELECT COUNT(*) FROM YourTable WHERE SomeColumn = 'SAM') > 0) --Only check this condition once
BEGIN
IF #TYPE=0
BEGIN
INSERT 'SOME VALUE' INTO YourTable WHERE <some condition>
END
IF #TYPE=1
BEGIN
DELETE FROM YourTable WHERE <some condition>
END
IF #TYPE=1
BEGIN
UPDATE YourTable
SET SomeColumn = 'SomeValue' WHERE <some condition>
END
END
ELSE
SELECT 'SAM was not supplied in the parameters or did not exist in table' -- or some logic
END

As per given requirement below stored procedure will help you
CREATE PROCEDURE ProcedureName (
#FN VARCHAR(30), #LN VARCHAR(30), #GNDR VARCHAR(30), #SLRY DECIMAL(18,3) , #TYPE INT )
As
BEGIN
IF #type=0 AND #FN='SAM'
BEGIN
--INSERT Command here
END
IF #type=1 AND #FN='SAM'
BEGIN
--DELETE Command here
END
IF #type=2 AND #FN='SAM'
BEGIN
--UPDATE Command here
END
END

Related

Using while exists in triggers sends the query in infinite loop

I created a trigger for insert and it works fine. This creates the trigger just fine:
While (exists(Select Id from #temp))
But the insert query is going into an infinite loop. I am using while exists to accommodate multiple insertions at a time. Can anyone tell me what is causing the infinite loop?
Create Table sqltutorial.Employee
(
Id int,
Name nvarchar(50),
Salary int,
Gender nvarchar(50),
DepartmentId int
)
Alter Trigger sqltutorial.trg_forinsert_Employee
on sqltutorial.Employee
For Insert
As
Begin
print 'Audit Begins'
Declare #Id int, #Name nvarchar(50), #Salary int,
#Gender nvarchar(50), #DepartmentId nvarchar(50)
Declare #AuditText nvarchar(500)
Select *
into #temp
from inserted
While (exists(Select Id from #temp))
Select #Id = Id from #temp
Select
#Id = Id, #Name = Name, #Salary = Salary,
#Gender = Gender, #DepartmentId = DepartmentID
from
#temp
Set #AuditText = 'New Record Inserted With Id='+Cast(#Id As nvarchar(50))+',Name='+#Name+' ,Salary='+CAST(#Salary as nvarchar(50))+' Gender'+#Gender
+' ,Department Id='+#DepartmentId+' on '+CAST((Select GETDATE()) AS nvarchar(50))+' by '+(Select system_user)
Insert into sqltutorial.AuditTrial
values (#AuditText)
Delete from #temp
where Id = #Id
print 'Audit Ends'
End
The reason for the infinite loop is that you did not specify a BEGIN and END to your WHILE loop code block like this:
WHILE SomeCondition = true
BEGIN
Do stuff
END
When you use WHILE and don't specify BEGIN..END, the WHILE loop repeats the next statement only, over and over until the WHILE condition is no longer met. And in your code, that would never happen, since the next statement doesn't delete anything from #temp.
In other words, in your code, this is what you are looping:
While (exists(Select Id from #temp))
Select #Id = Id from #temp
The rest of the code after this never even executes because the WHILE loop never exits.
You don't need to use all the variables and temp tables in your trigger simply do the following:
ALTER TRIGGER sqltutorial.trg_forinsert_Employee
ON sqltutorial.Employee
FOR INSERT
AS
BEGIN
SET NOCOUNT ON;
INSERT INTO sqltutorial.AuditTrial
SELECT
' New Record Inserted With Id=' + CAST([Id] AS NVARCHAR(50)) +
',Name=' + [Name] +
',Salary=' + CAST(Salary AS NVARCHAR(50)) +
',Gender' + Gender +
',Department Id=' + DepartmentId +
' on ' + CAST((SELECT GETDATE()) AS NVARCHAR(50)) +
' by ' + CAST(system_user AS NVARCHAR(256))
FROM
inserted
END

sql linked server Insert statement fails inside the cursor

Insert statement fails inside the cursor when I try to insert values in to SQL linked server.
If I run the same insert statement outside cursor then it works fine. Is there any settings to be done while creating linked server?
Error message:
OLE DB provider "SQL...." for linked server "" returned message "The parameter is incorrect.".
This is my Code Linked Server in Cursor
SET NOCOUNT ON;
DECLARE #SUBCATEGORY_NAME AS VARCHAR(100), #CategoryStatus AS BIT, #BRAND_NAME AS VARCHAR(100), #BrandMasterStatus AS BIT, #BrandManfacturerName AS VARCHAR(MAX), #PRODUCT_NAME VARCHAR(100), #ProductStatus AS BIT,
#ProductIsReturnable AS BIT, #PRINT_ON_RECEIPT AS VARCHAR(40), #TenantId INT, #CreationTime DATETIME2, #ParentId INT, #BAR_CODE_NO AS VARCHAR(40),
#TAX_CODE AS VARCHAR(MAX), #TaxName AS VARCHAR(MAX), #TaxInclusive AS BIT, #TAX_PERCENTAGE AS FLOAT, #TaxStartDateTime DATETIME2, #BUSINESS_TYPE VARCHAR(20);
--PRINT '-------- Product table migration --------';
DECLARE Product_Cursor CURSOR FOR
SELECT
SC.SUBCATEGORY_NAME,CASE WHEN SC.DEFUNCT_IND = 'N' THEN 1 ELSE 0 END AS CategoryStatus,
BM.BRAND_NAME,CASE WHEN BM.DEFUNCT_IND = 'N' THEN 1 ELSE 0 END AS BrandMasterStatus,BM.MANUFACTURER AS BrandManfacturerName,
P.PRODUCT_NAME,CASE WHEN P.DEFUNCT_IND = 'N' THEN 1 ELSE 0 END AS ProductStatus,
CASE WHEN P.RETURNABLE = 'Y' THEN 1 ELSE 0 END AS ProductIsReturnable,
P.PRINT_ON_RECEIPT,
--SubCategoryId,
--BrandId,
--1 AS TaxId,
1 AS TenantId,
GETDATE() AS CreationTime,
0 AS ParentId,
P.BAR_CODE_NO,
TS.TAX_CODE,
TS.TAX_DESC AS TaxName,
CASE WHEN TS.TAX_INCLUDED = '1' THEN 1 ELSE 0 END AS TaxInclusive,
TS.TAX_PERCENTAGE,
TS.EFFECTIVE_DATE AS TaxStartDateTime,
P.BUSINESS_TYPE
FROM CISPROD.dbo.PRODUCT AS P
RIGHT OUTER JOIN CISPROD.dbo.SUBCATEGORY AS SC ON SC.SUBCATEGORY_ID = P.SUBCATEGORY_ID
FULL OUTER JOIN CISPROD.dbo.BRANDMSTR AS BM ON BM.BRANDMSTR_ID = P.BRANDMSTR_ID
FULL OUTER JOIN CISPROD.dbo.TAX_SETUP AS TS ON TS.TAX_CODE = P.TAX_GROUP
OPEN Product_Cursor
FETCH NEXT FROM Product_Cursor
INTO #SUBCATEGORY_NAME,#CategoryStatus,#BRAND_NAME, #BrandMasterStatus, #BrandManfacturerName, #PRODUCT_NAME, #ProductStatus, #ProductIsReturnable,
#PRINT_ON_RECEIPT, #TenantId, #CreationTime,#ParentId,#BAR_CODE_NO,#TAX_CODE, #TaxName, #TaxInclusive, #TAX_PERCENTAGE, #TaxStartDateTime, #BUSINESS_TYPE;
BEGIN TRANSACTION
BEGIN TRY
WHILE ##FETCH_STATUS = 0
BEGIN
--PRINT ' '
--DECLARE #message VARCHAR(MAX)
--SELECT #message = '----- Products CISPROD: ' + #PRODUCT_NAME
--PRINT #message
--Insert Product Categories Table
DECLARE #CategoryId INT
IF ISNULL(#SUBCATEGORY_NAME,'') <>''
BEGIN
---IF NOT EXISTS(SELECT [Name] FROM ProductCategories WHERE ISNULL([Name], '') = ISNULL(#SUBCATEGORY_NAME,''))
IF NOT EXISTS(SELECT [Name] FROM [AZUREDATABASE].[sds-pos-storiveo-db].dbo.ProductCategories WHERE [Name] = #SUBCATEGORY_NAME)
BEGIN
INSERT INTO [AZUREDATABASE].[sds-pos-storiveo-db].dbo.ProductCategories([Name],CreationTime,Inactive,ParentId,TenantId) VALUES(#SUBCATEGORY_NAME,#CreationTime,#CategoryStatus,#ParentId,#TenantId)
SELECT #CategoryId = ##IDENTITY
END
ELSE
BEGIN
SELECT #CategoryId = Id FROM [AZUREDATABASE].[sds-pos-storiveo-db].dbo.ProductCategories WHERE [Name] = #SUBCATEGORY_NAME
END
END
--Insert Product Brand Table
DECLARE #BrandId INT
--DECLARE #DefaultBrandId INT
--SET #DefaultBrandId = 1
IF ISNULL(#BRAND_NAME,'') <>''
BEGIN
--IF NOT EXISTS(SELECT BrandName FROM ProductBrands WHERE ISNULL(BrandName,'') = ISNULL(#BRAND_NAME,''))
IF NOT EXISTS(SELECT BrandName FROM [AZUREDATABASE].[sds-pos-storiveo-db].dbo.ProductBrands WHERE BrandName = #BRAND_NAME)
BEGIN
INSERT INTO [AZUREDATABASE].[sds-pos-storiveo-db].dbo.ProductBrands(BrandName,ManufacturerName,CreationTime,Inactive) VALUES(#BRAND_NAME,#BrandManfacturerName,#CreationTime,#BrandMasterStatus)
SELECT #BrandId = ##IDENTITY
END
ELSE
BEGIN
SELECT #BrandId = Id FROM [AZUREDATABASE].[sds-pos-storiveo-db].dbo.ProductBrands WHERE BrandName = #BRAND_NAME
END
END
--ELSE
--BEGIN
-- SET #BrandId = #DefaultBrandId
--END
--Insert Tax Table Records
DECLARE #TaxId INT
IF ISNULL(#TAX_CODE,'') <>''
BEGIN
IF NOT EXISTS(SELECT Code FROM [AZUREDATABASE].[sds-pos-storiveo-db].dbo.Taxes WHERE Code = #TAX_CODE)
BEGIN
INSERT INTO [AZUREDATABASE].[sds-pos-storiveo-db].dbo.Taxes(Code,Inactive,IsInclusive,[Name],TaxTypeId,TenantId) VALUES(#TAX_CODE,1,#TaxInclusive,#TaxName,1,#TenantId)
SELECT #TaxId = ##IDENTITY
INSERT INTO [AZUREDATABASE].[sds-pos-storiveo-db].dbo.TaxSchedules([Percentage],StartDateTime,TaxId) VALUES(#TAX_PERCENTAGE,#TaxStartDateTime,#TaxId)
END
ELSE
BEGIN
SELECT #TaxId = Id FROM [AZUREDATABASE].[sds-pos-storiveo-db].dbo.Taxes WHERE Code = #TAX_CODE
END
END
--Insert Product Table Records
DECLARE #ProductId INT
IF ISNULL(#PRODUCT_NAME,'') <>''
BEGIN
IF (#BUSINESS_TYPE = 'NF')
BEGIN
INSERT INTO [AZUREDATABASE].[sds-pos-storiveo-db].dbo.Products([Name],Inactive,IsReturnable,PrintName,
ProductBrandId,ProductCategoryId,TaxId,TenantId,CreationTime)
VALUES(#PRODUCT_NAME,#ProductStatus,#ProductIsReturnable,#PRINT_ON_RECEIPT,#BrandId,#CategoryId,#TaxId,#TenantId,#CreationTime)
END
ELSE
BEGIN
INSERT INTO [AZUREDATABASE].[sds-pos-storiveo-db].dbo.FuelProducts([Name],Inactive,PrintName,
ProductCategoryId,TaxId,TenantId,CreationTime)
VALUES(#PRODUCT_NAME,#ProductStatus,#PRINT_ON_RECEIPT,#CategoryId,#TaxId,#TenantId,#CreationTime)
END
SELECT #ProductId = ##IDENTITY
END
--Insert Product Barcode Records
IF ISNULL(#BAR_CODE_NO,'') <>''
BEGIN
IF (#BUSINESS_TYPE = 'NF')
BEGIN
INSERT INTO [AZUREDATABASE].[sds-pos-storiveo-db].dbo.ProductBarcodes(Barcode,Inactive,ProductId)VALUES(#BAR_CODE_NO,#ProductStatus,#ProductId)
END
END
FETCH NEXT FROM Product_Cursor
INTO #SUBCATEGORY_NAME,#CategoryStatus,#BRAND_NAME, #BrandMasterStatus, #BrandManfacturerName, #PRODUCT_NAME, #ProductStatus, #ProductIsReturnable,
#PRINT_ON_RECEIPT, #TenantId, #CreationTime, #ParentId, #BAR_CODE_NO, #TAX_CODE, #TaxName, #TaxInclusive, #TAX_PERCENTAGE, #TaxStartDateTime,#BUSINESS_TYPE
END
END TRY
BEGIN CATCH
ROLLBACK TRANSACTION
-- any other logiing or cleanup
END CATCH
IF ##TranCount>0 -- Transaction still open, so must have succeeded. If rolled back, trancount would be 0
COMMIT TRANSACTION
CLOSE Product_Cursor;
DEALLOCATE Product_Cursor;

procedure that returns varchar

I tried to make a function that returns varchar, but I can't because I'm using CREATE TABLE inside, and when I'm creating it with a procedure I can't return a value.
I wanted to know if you have some advice.
I made this just to make a string with emails separated by ";" so I can have all the "manager" mails in one varchar (for the recipients).
ALTER procedure [dbo].[Manager_email]
AS
BEGIN
declare #mails varchar (max),
#number_of_mails int,
#counter int
set #counter=2
create table #temp ( id int identity, email varchar(30))
insert into #temp (email)
select Email
from hr.Employees
where lower (EmpRole) like 'manager'
set #number_of_mails=##ROWCOUNT
set #mails = (select email from #temp where id =1 ) + ';'
while #counter <= #number_of_mails
BEGIN
set #mails = #mails + (select email from #temp where id =#counter ) + ';'
set #counter = #counter+1
END
drop table #temp
return cast (#mails as varchar (200))
END
You can only return integer value back from the procedure, If you want to return varchar value from procedure its good to make use of output variable in procedure.
Example
CREATE PROCEDURE Sales.uspGetEmployeeSalesYTD
#SalesPerson nvarchar(50),
#SalesYTD money OUTPUT
AS
SET NOCOUNT ON;
SELECT #SalesYTD = SalesYTD
FROM Sales.SalesPerson AS sp
JOIN HumanResources.vEmployee AS e ON e.BusinessEntityID = sp.BusinessEntityID
WHERE LastName = #SalesPerson;
RETURN
like in above procedure return #SalesYTD from procedure.
you can check full post on MSDN : Returning Data by Using OUTPUT Parameters
You can use function instead
CREATE FUNCTION Manager_email ()
RETURNS varchar(max)
AS
BEGIN
declare #email varchar(30)
declare #emails varchar(max)
set #emails = ''
declare cur cursor for
select Email
from hr.Employees
where lower (EmpRole) like 'manager'
open cur
fetch next from cur into #email
while ##fetch_status = 0
begin
set #emails = #emails + #email + ';'
fetch next from cur into #email
end
close cur
deallocate cur
return #emails
END
You can use table variable instead of temporary table. In that case you can continue to use UDF.

Stored Procedure OutPut Parameters

i need to write a stored procedure which will return a string.logic is
when user try to insert a new record i need to check whether that record already exist.if exist need to return msg "Record exist" else return "Inserted"
following is what i have done for the moment and i'm stuck here.can some one help me to complete the procedure
CREATE PROCEDURE [dbo].[spInsetPurpose]
#Purpose VARCHAR(500),
#Type VARCHAR(6),
#Result VARCHAR(10)= NULL OUTPUT
AS
BEGIN
Declare #Position VARCHAR(20)
DECLARE #TempTable TABLE (Purpose VARCHAR(500))
INSERT INTO #TempTable
SELECT Purpose FROM tblPurpose WHERE Purpose=#Purpose
INSERT INTO tblPurpose(Purpose,[Type]) VALUES(#Purpose,#Type)
END
To check if the row already exists you can do
If Exists (Select Top 1 1 from tblPurpose where Purpose = #Purpose and [Type] = #Type)
Begin
Insert Into tblPurpose
(Purpose, [Type])
Select
#Purpose, #Type
SET #Result = 'Inserted'
End
Else
Begin
SET #Result = 'Record exists'
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