How to check if there are rows and execute an Insert - sql

I got the following SQL Code, I need
Execute an Insert only if the code returns more than 0 rows.
Put messages on the screen for the person who executes the script, saying
No missing rows were detected or
3 missing rows were detected and added.
select * from DistributionKey_Section where SectionID
not in
(
select siteid from Site where SiteTypeCodeID IN(8)
)
and DistributionKeyID NOT IN
(
select DistributionKeyID from DistributionKey where UnitInclusive=1
)

DECLARE
#MissingRows int,
#InsertedRows int
SELECT *
FROM DistributionKey_Section
WHERE SectionID NOT IN ( select siteid from Site where SiteTypeCodeID IN(8) ) AND
DistributionKeyID NOT IN ( SELECT DistributionKeyID FROM DistributionKey WHERE
UnitInclusive=1 )
SET #MissingRows = ##ROWCOUNT
IF #MissingRows > 0
BEGIN
<Insert Statement/Logic>
SET #InsertedRows = ##ROWCOUNT
PRINT CAST(#InsertedRows as varchar(5)) + ' missing rows were detected and added'
IF #MissingRows <> #InsertedRows
BEGIN
RAISERROR('The number of rows inserted does not equal the number of rows missing', 16, 1)
END
END
ELSE
PRINT 'No Missing Rows Detected'

Related

how to show message if column have equal value

i Have the following table like-
column_no count_no
------------------------
1 2
2 2
3 2
if find all count_no value is same i want to return a custom message using strored procedure.
You can try this:
SET NOCOUNT ON
declare #msg varchar(500) = 'your custom message'
Create table #temp
(
column_no int ,
count_no int
)
insert into #temp
values
(1,2),
(2,2),
(3,2)
IF (select count(*)
from
(select distinct count_no from #temp ) as diff) <> 1
BEGIN
select 1 where 1<>1 --select nothing
END
ELSE
BEGIN
print #msg
END
drop table #temp
I'm not sure what you want to return if there are any differences, but something like this returns a result set with 0 or one rows:
select 'All same'
from t
having min(count_no) = max(count_no);
If you want to print the result:
if (not exists (select 1 from t having min(count_no) <> max(count_no)))
begin
print 'All same'
end;

IF EXISTS (SELECT) in SQL Server not working as expected

I have a code like this:
IF EXISTS (SELECT * FROM table WHERE id = #id)
BEGIN
UPDATE table
SET stock = stock + #stock
WHERE id = #id
END
ELSE
BEGIN
INSERT INTO [table] ([id], [name], [stock])
VALUES (#id, #name, #stock)
END
But, this code isn't working and I am unable to find the root cause for the same. Can someone please help me?
I do not see any error in your code, I tried to replicate the process and it is working fine for me. Can you tell me what is the error you are facing exactly.
The following is the code I tried to replicate your scenario:
CREATE TABLE stocks (
id INT
,NAME VARCHAR(100)
,stock BIGINT
)
CREATE PROCEDURE InsertStocks #id INT
,#name VARCHAR(100)
,#stock BIGINT
AS
BEGIN
IF EXISTS (
SELECT *
FROM stocks
WHERE id = #id
)
BEGIN
UPDATE stocks
SET stock = stock + #stock
WHERE id = #id
END
ELSE
BEGIN
INSERT INTO stocks (
[id]
,[name]
,[stock]
)
VALUES (
#id
,#name
,#stock
)
END
END
INSERT INTO stocks
VALUES (
1
,'abc'
,200
)
INSERT INTO stocks
VALUES (
2
,'abc'
,300
)
INSERT INTO stocks
VALUES (
3
,'abc'
,500
)
EXEC Insertstocks 1
,'abc'
,700
This is updated successfully in my case.
table is a reserved keyword. so I guess you have a trivial syntax error: Incorrect syntax near the keyword 'table'. Wrap it with [], as you already did for INSERT statement
IF EXISTS (
SELECT * FROM [table] WHERE id = #id)
BEGIN
UPDATE [table] SET stock = stock + #stock
WHERE id = #id
END
ELSE
BEGIN
INSERT INTO [table] ([id]
,[name]
,[stock])
VALUES
(
#id,#name,#stock
)
END
Your code and syntax is correct. Let's see a sample example:
if EXISTS(select * from dbo.tbName where Id=1)
BEGIN
print 1
END
ELSE
BEGIN
print 2
END

While Loop SAP B1 SQL stored procedure for blocking

I have an issue with my stored procedure SAP B1.
What I'm trying to do here is storing the sum of the quantity, group by the manufacturing order and insert it into the temp table. Then use a while loop to go thru each ID to compare with the user table [#FGTRACKING] and block if
temp.quantity > sum(quantity) in [#FGTracking].
However this is not working, the transaction still passed the stored procedure block. I suspect there is something wrong with my syntax.
IF #transaction_type IN ('A') AND #object_type = '67'
BEGIN
declare #top as int
declare #temp table (id int,quantity int NOT NULL, monum int NOT NULL)
insert into #temp (id, quantity,monum)
select row_number() over (order by (select NULL)), sum(quantity) as quantity, u_shipment_line as monum
from wtr1 t1
where t1.docentry = #list_of_cols_val_tab_del
group by u_shipment_line
set #top = 1
WHILE #top <= (select count(monum) from #temp)
BEGIN
IF EXISTS (select t100.monum from #temp t100
where t100.quantity > (select sum(t111.u_transfer)
from [#FGTRACKING] t111 where t111.u_mo_num = t100.monum
group by t111.u_mo_num) and t100.id = #top)
BEGIN
SELECT #Error = 666, #error_message = 'Over-transfer'
END
ELSE
set #top = #top + 1
END
END
It looks like you're only incrementing your iterator (#top) when you don't encounter your error condition, so if your error condition triggers, you're stuck in an infinite loop.
Get rid of your "else" and always increment #top, or alternatively break out of your while loop when you hit your error condition.
...
ELSE -- Get rid of this else
set #top = #top + 1
...

What is best way to fetch related rows in each table of dataset in sql

Suppose I have 2 tables
1. Artical(ID,Description,PubDate)
2. ArticalMedia(ID,ArticalID,MediaURL)
Now I want to fetch 2 tables within stored procedure.
Table1: Top 5 Latest news
Table2: All Media's of Top 5 news selected in Table1
I know we can achieve this using #Temp tables. I this only & best way? Or do we have any other method to achieve same thing?
Simple 2 select statements might lead to wrong data, plesae see following example:
select top 5 * from Artical order by PubDate desc
retuns Artical's : 5,4,3,2,1
select * from ArticalMedia where ArticalID in (select top 5 ID from Artical order by PubDate desc)
can return Medias of 6,5,4,3,2. cause new Artical might be inserted in database, after first select & before second select.
Get the TOP 5 records and then join them to the ArticleMedia table:
SELECT *
FROM
(
SELECT TOP 5 ID,Description,PubDate
FROM Artical
ORDER BY PubDate DESC
) DS
INNER JOIN ArticleMedia AM
ON DS.[Id] = AM.[id]
Try this optimized query with light weight execution plan:
SELECT A.*,AM.*
FROM ArticalMedia AS AM INNER JOIN
Article AS A ON AM.ArticleID = A.ID
WHERE (AM.ArticleID IN
(SELECT TOP (5) ID
FROM Article
ORDER BY PubDate DESC))
ORDER BY A.PubDate DESC
Edit 2
Create Table valued function in SQL fn_split:
CREATE FUNCTION [dbo].[fn_Split](#sText varchar(8000), #sDelim varchar(20) = ' ')
RETURNS #retArray TABLE (idx smallint Primary Key, value varchar(8000))
AS
BEGIN
DECLARE #idx smallint,
#value varchar(8000),
#bcontinue bit,
#iStrike smallint,
#iDelimlength tinyint
IF #sDelim = 'Space'
BEGIN
SET #sDelim = ' '
END
SET #idx = 0
SET #sText = LTrim(RTrim(#sText))
SET #iDelimlength = DATALENGTH(#sDelim)
SET #bcontinue = 1
IF NOT ((#iDelimlength = 0) or (#sDelim = 'Empty'))
BEGIN
WHILE #bcontinue = 1
BEGIN
--If you can find the delimiter in the text, retrieve the first element and
--insert it with its index into the return table.
IF CHARINDEX(#sDelim, #sText)>0
BEGIN
SET #value = SUBSTRING(#sText,1, CHARINDEX(#sDelim,#sText)-1)
BEGIN
INSERT #retArray (idx, value)
VALUES (#idx, #value)
END
--Trim the element and its delimiter from the front of the string.
--Increment the index and loop.
SET #iStrike = DATALENGTH(#value) + #iDelimlength
SET #idx = #idx + 1
SET #sText = LTrim(Right(#sText,DATALENGTH(#sText) - #iStrike))
END
ELSE
BEGIN
--If you can’t find the delimiter in the text, #sText is the last value in
--#retArray.
SET #value = #sText
BEGIN
INSERT #retArray (idx, value)
VALUES (#idx, #value)
END
--Exit the WHILE loop.
SET #bcontinue = 0
END
END
END
ELSE
BEGIN
WHILE #bcontinue=1
BEGIN
--If the delimiter is an empty string, check for remaining text
--instead of a delimiter. Insert the first character into the
--retArray table. Trim the character from the front of the string.
--Increment the index and loop.
IF DATALENGTH(#sText)>1
BEGIN
SET #value = SUBSTRING(#sText,1,1)
BEGIN
INSERT #retArray (idx, value)
VALUES (#idx, #value)
END
SET #idx = #idx+1
SET #sText = SUBSTRING(#sText,2,DATALENGTH(#sText)-1)
END
ELSE
BEGIN
--One character remains.
--Insert the character, and exit the WHILE loop.
INSERT #retArray (idx, value)
VALUES (#idx, #sText)
SET #bcontinue = 0
END
END
END
RETURN
END
Then the query will be:
DECLARE #tmp nvarchar(max);
select #tmp = stuff((select top 5 ', ', cast(id as nvarchar(max))
FROM Article
ORDER BY PubDate DESC
for xml path ('')
), 1, 2, '');
SELECT A.*,AM.*
FROM ArticalMedia AS AM INNER JOIN
Article AS A ON AM.ArticleID = A.ID
WHERE (AM.ArticleID IN (select value from dbo.fn_split(#tmp,',')))
ORDER BY A.PubDate DESC
Use a CTE to keep it simple:
with Top5Artical as (
select top (5) Artical.ID as ArticleID
from Artical
order by Artical.PubDate desc
),
insert into #Table1
select Top5.ArticalID,
Art.Description,
Art.PubDate
from Top5Artical as Top5
inner join Artical as Art
on Top5.ArticalID = Art.ID
order by Top5.PubDate desc;
insert into #Table2
select Top5.ArticalID,
ArtMedia.ID,
ArtMedia.URL
from Top5Artical as Top5
inner join ArticalMedia as ArtMedia
on Top5.ArticalID = ArtMedia.ArticalID
order by Top5.PubDate desc;
select * from #Table1;
select * from #Table2;

get error in sql stored procedure table type

i have this procedure and i want insert list of value into table,and i want check duplicate value and return this but i get this error
ERROR:
Subquery returned more than 1 value. This is not permitted when the subquery follows =, !=, <, <= , >, >= or when the subquery is used as an expression.
ALTER PROCEDURE [dbo].[insertData]
#Value insertTbl READONLY,
#Result INT OUTPUT
AS
BEGIN
BEGIN TRY
IF (SELECT COUNT(Id)
FROM #Values
WHERE Id IN (SELECT Id
FROM [dbo].[username])) = 0
BEGIN
INSERT INTO dbo.username ( Id, NAME )
SELECT Id,
NAME
FROM #Values
WHERE Id NOT IN (SELECT Id
FROM [dbo].[username])
SELECT #Result = 101
END
ELSE
SELECT #Result = (
SELECT Id
FROM #Values
WHERE Id IN (SELECT Id
FROM [dbo].[username])
)
END TRY
BEGIN CATCH
SELECT ERROR_MESSAGE()
END CATCH
END
Please try this.
I have changed the return type to VARCHAR. That would return a CSV (e.g. 1,3,9...)
The other option is to return a result set. For this replace SELECT #Result = to INSERT INTO #Result...
Hope this helps.
ALTER PROCEDURE [dbo].[insertData]
#Value insertTbl READONLY,
#Result VARCHAR(500) OUTPUT
AS
BEGIN
BEGIN TRY
IF (SELECT COUNT(Id)
FROM #Values
WHERE Id IN (SELECT Id
FROM [dbo].[username])
) = 0
BEGIN
INSERT INTO dbo.username (Id,NAME)
SELECT Id,
NAME
FROM #Values
WHERE Id NOT IN (SELECT Id
FROM [dbo].[username])
SELECT #Result = 101
END
ELSE
BEGIN
SELECT #Result = (SELECT STUFF((SELECT ', ' + CAST(ID AS VARCHAR(5))
FROM #Values
WHERE Id IN (SELECT Id
FROM [dbo].[username])
ORDER BY Id FOR XML PATH('')),1,2,''))
END
END TRY
BEGIN CATCH
SELECT ERROR_MESSAGE()
END CATCH
END
Probably this line
SELECT #Result=(SELECT Id FROM #Values WHERE Id IN (SELECT Id FROM [dbo].[username]))
return more than one row. You should change the query to return only one value as below
SELECT #Result=(SELECT top 1 Id FROM #Values WHERE Id IN (SELECT Id FROM [dbo].[username]))
or you should change your logic. Alternative way is to use temprary table to return listo of ID. Try below solution
-- create temporary table before (!) creating procedure
create table #Resulttab
(
Result int
)
go
ALTER PROCEDURE [dbo].[insertData]
#Value insertTbl READONLY,
#Result INT OUTPUT -- in this solution I think you don't need this parameter
AS
BEGIN
BEGIN TRY
IF (SELECT COUNT(Id)
FROM #Values
WHERE Id IN (SELECT Id
FROM [dbo].[username])) = 0
BEGIN
INSERT INTO dbo.username ( Id, NAME )
SELECT Id,
NAME
FROM #Values
WHERE Id NOT IN (SELECT Id
FROM [dbo].[username])
SELECT #Result = 101
END
ELSE
insert into #Resulttab
SELECT Id
FROM #Values
WHERE Id IN (SELECT Id
FROM [dbo].[username])
END TRY
BEGIN CATCH
SELECT ERROR_MESSAGE()
END CATCH
END
go
You can use it that way:
-- create temporary table before run procedure
create table #Resulttab
(
Result int
)
-- run procedure with parameters
exec insertData ...
--after run procedure you can check list of your IDs
select Result from #Resulttab