Is there a way to manually set ##ROWCOUNT? - sql

Consider this script to illustrate what I want:
SET NOCOUNT OFF
DECLARE #table TABLE(col1 INT IDENTITY(1,1), col2 INT)
INSERT INTO #table(col2) VALUES (1),(2),(3),(4)
This will show (4 row(s) affected)
Now what I want:
SET NOCOUNT ON
DECLARE #table TABLE(col1 INT IDENTITY(1,1), col2 INT)
INSERT INTO #table(col2) VALUES (1),(2),(3),(4)
-- do other stuff...
SET NOCOUNT OFF
SELECT ##ROWCOUNT = 666 -- return this value to client with ExecuteNonQuery()
Obviously SELECT ##ROWCOUNT = 666 is incorrect syntax.
I need to set ##ROWCOUNT manually, and return that value to a c# client with rowsAffected = ExecuteNonQuery(...)
Can this be done?
(Note: I use a stored procedure, and do not want to use an OUT parameter or return a recordset)

The obvious way to create an artificial (rows affected) message is to perform an action that affects that number of rows whilst having as few side effects as possible:
declare #t table (n int not null)
;With Numbers (n) as (
select ROW_NUMBER() OVER (ORDER BY so1.object_id)
from sys.objects so1,sys.objects so2
)
insert into #t(n) select n from Numbers where n<=666
Whether it will be sufficient to trick ExecuteNonQuery I couldn't say. (If you have an actual Numbers table you can use that in place of the CTE, though you may have to adjust the filtering if it contains 0 or negative numbers)

Another way to achieve this is:
SET NOCOUNT ON
-- Do stuff
SET NOCOUNT OFF
-- Run the actual query that will affect the specified number of rows
SET NOCOUNT ON
-- Do more stuff
Example:
CREATE PROCEDURE Example1
AS
SET NOCOUNT ON
DECLARE #table TABLE(col1 INT IDENTITY(1,1), col2 INT)
INSERT INTO #table(col2) VALUES (1),(2),(3),(4)
SET NOCOUNT OFF
SELECT a.*
INTO #NoWhere
FROM #table AS a
CROSS JOIN #table AS b
SET NOCOUNT ON
SELECT COUNT(*)
FROM #table AS a
CROSS JOIN #table AS b
GO;
EXEC Example1
-- (16 row(s) affected)

Related

How to insert values in temp table on multiple times

I have this code. Can I insert values into a temp table multiple times? I have list of ids (i.e. 1000 ids). I want to insert this by loop.
DECLARE #tempTable TABLE(col1 INT)
FOR (#ids IS NOT NULL) {
INSERT INTO #tempTable VALUES(#ids)
}
SELECT * FROM #tempTable
Even though it is possible using WHILE loop I will suggest you to go with SET Based approach
Why cant you just do this
INSERT INTO #tempTable (ID)
select Id from yourlist
SQL Server is not support FOR loop. You need to use WHILE loop instead.
SQL Server Looping
You can use a while statement as said Jitendra Tiwari:
DECLARE #tempTable TABLE(col1 INT)
DECLARE #num int
SET #num = 1
WHILE #num <= 1000
BEGIN
INSERT INTO #tempTable VALUES (#num) --(#ids)
SET #num = #num + 1
END
SELECT * FROM #tempTable

Iterate through values of a table variable in a stored procedure

I am writing a stored proc as follows:
CREATE PROCEDURE ListByOrderRequestId
#EntityId int,
#EntityTypeId varchar(8)
AS
BEGIN
SET NOCOUNT ON;
Declare #IDS table(OrderRequestId int)
INSERT INTO #IDS
SELECT OrderRequestTaskId
FROM OrderRequestTask ORT WITH (NOLOCK)
WHERE ORT.OrderRequestId = #EntityId
SELECT N.EntityNoteId AS Id,
N.UpdateDate AS DateStamp,
N.EntityNoteText,
N.EntityId,
N.EntityNoteTypeId,
N.EntityTypeId
FROM EntityNote N
WHERE (N.EntityId = #EntityId AND N.EntityTypeId ='ORDREQ')
*OR(N.EntityId = #IDS VAL1 AND N.EntityTypeId ='TASK')
OR(N.EntityId = #IDS VAL2 AND N.EntityTypeId ='TASK')*
END
The table #IDS can have 0 or 1 or more values in it. I want to loop through the values in #TDS and create the where clause above accordingly. Please help me.
As opposed to looping through the table, you could just use it in your where clause like this:
Select * From {Your Table} Where ID in (Select OrderRequestId From IDS)
This is much faster than looping.

sql: my data repeats itself

When I execute my code it works but my data repeats itself. The print is just to see what it gets.
DECLARE #Variable1 NVARCHAR(MAX)
DECLARE #Variable2 NVARCHAR(MAX)
DECLARE #Variable3 NVARCHAR(MAX)
CREATE TABLE #Temp1 (MAI_ID BIGINT, FUN_ID BIGINT)
CREATE TABLE #tmp2 (MAI_ID BIGINT, Variable1 NVARCHAR(MAX),Variable2 NVARCHAR(MAX), Variable3 NVARCHAR(MAX))
INSERT INTO #Temp1
SELECT TOP 10 ISD_MainID, ISNULL(ISD_FUNID,0)
FROM [dev_SAB_EM].[dbo].[SiteDetails]
ORDER BY ISD_ID DESC
DECLARE #MAI_ID BIGINT
DECLARE #FUN_ID BIGINT
WHILE (SELECT COUNT(MAI_ID) FROM #Temp1) <> 0
BEGIN
SELECT TOP 1 #MAI_ID = MAI_ID, #FUN_ID = FUN_ID FROM #Temp1
PRINT #MAI_ID
PRINT #FUN_ID
SELECT #Variable1 = ISNULL(FUN_Name,'') FROM [dev_SAB_Man].[dbo].[fx_GetFUNStructureCTE_Asc] (#FUN_ID) WHERE FUN_Level = 1
SELECT #Variable2 = ISNULL(FUN_Name,'') FROM [dev_SAB_Man].[dbo].[fx_GetFUNStructureCTE_Asc] (#FUN_ID) WHERE FUN_Level = 2
SELECT #Variable3 = ISNULL(FUN_Name,'') FROM [dev_SAB_Man].[dbo].[fx_GetFUNStructureCTE_Asc] (#FUN_ID) WHERE FUN_Level = 3
INSERT INTO #tmp2(MAI_ID, Variable1, Variable2, Variable3)
SELECT #MAI_ID, #Variable1, #Variable2, #Variable3
DELETE FROM #Temp1 WHERE MAI_ID = #MAI_ID AND FUN_ID = #FUN_ID
END
SELECT * FROM #tmp2
DROP TABLE #Temp1
DROP TABLE #tmp2
fx_GetFUNStructureCTE_Asc
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE FUNCTION [dbo].[fx_GetFUNStructureCTE_Asc] (#param_FUNID int)
RETURNS #FUN_Names table
(
[Level_Label] nvarchar(255),
[FUN_Name] nvarchar(255),
[FUN_Level] int,
[FUN_ID] int
)
AS
BEGIN
with cte([Level_Label],[FUN_Name],[FUN_Level],[FUN_ID],[FUN_FUNID]) as
(
select ful1.FUL_Name,fu1.FUN_Name,fu1.FUN_Level,fu1.FUN_ID,fu1.FUN_FUNID
from FunctionalUnits fu1
inner join FunctionalUnitLevels ful1 on ful1.FUL_Level=fu1.FUN_Level
where fu1.FUN_ID=#param_FUNID
union all
select ful2.FUL_Name,fu2.FUN_Name,fu2.FUN_Level,fu2.FUN_ID,fu2.FUN_FUNID
from FunctionalUnits fu2
inner join FunctionalUnitLevels ful2 on ful2.FUL_Level=fu2.FUN_Level
inner join CTE a on a.FUN_FUNID=fu2.FUN_ID
)
insert into #FUN_Names
([Level_Label],[FUN_Name],[FUN_Level],[FUN_ID])
(select [Level_Label],[FUN_Name],[FUN_Level],[FUN_ID] from cte
where exists (select FUA_isActive from FunctionalUnitsActive where FUA_isActive=1))
return
RETURN
END
GO
Any suggestions or anything that can hep me?
Ok I've added fx_GetFUNStructureCTE_Asc
Considering the informations you gave, besides what #Lamak said, it also may depend on what the the field ISD_FUNID values has on [dev_SAB_EM].[dbo].[SiteDetails] table. If they are all the same on every record then there's no problem with your code...
But, it's a basic assumption...
And, assuming what you said on your comment as the value of ISD_FUNID being NULL, what may be happening is this: when all the value of the field FUN_ID are 0 on table #Temp1 what will happen when you execute the query on the function [dev_SAB_Man].[dbo].[fx_GetFUNStructureCTE_Asc] is that all rows will loop while the assignment occurs, setting the variables values to the last one returned by the function.
It'll make all the variables values be the same for all #tmp2 rows. You may need to improve the function call to return just one value.

how to use select expression in while loop in sql server?

I need to use a select expression in a while loop and I use the below sample code:
declare #i integer
set #i=1
while (#i<10)
begin
select #i as m;
set #i=#i+1
END
this code returns 10 separate table! I want it to return all select results in one table... is that possible? if yes... how?
You can use a temp table or table variable for this.
Here's how to do it using a temp table.
CREATE TABLE #t (m INT)
DECLARE #i INT
SET #i=1
WHILE (#i<10)
BEGIN
INSERT INTO #t SELECT #i
SET #i=#i+1
END
SELECT m FROM #t
Very similar with a table variable
DECLARE #t TABLE (m INT)
DECLARE #i INT
SET #i=1
WHILE (#i<10)
BEGIN
INSERT INTO #t SELECT #i
SET #i=#i+1
END
SELECT m FROM #t
It is not possible. Each SELECT statement generates its own result set. You can use temp table to add results of each iteration and then get all in one table. To generate sequence of integers you can use this (for SQL SERVER 2005 + )
;WITH CTE
AS
(
SELECT 1 N
UNION ALL
SELECT N + 1 FROM CTE
WHERE N<10
)
SELECT N FROM CTE
squillman got it...with #t (create table # - table persisted at top-level scope while session is open - if you have several batch statements, you can reference this table in any after declaration until you drop the table)
Cris also got it with #test (declare # table - variable - only persisted in the current scope - single execution batch block...note that there are several performance issues that can be introduced if you use this)
the last type of temp table you can use is a global temp table (create table ## - lasts as long as the session that created it stays open or until it is dropped)
with #t, you may want to add this to the beginning of your script if you don't close the session:
IF OBJECT_ID('tempdb..#t') IS NOT NULL
DROP TABLE #t
Enjoy the temp tables!
declare #i integer
DECLARE #test TABLE(
m /*your data type*/
)
set #i=1
while (#i<10)
begin
insert into #test select #i;
set #i=#i+1
END
select * from #test

Shrink a Bulk insertion into a loop-based

Want to change this piece of SQL query into a loop version which
Could Select-Insert records by 1000 items per iteration.
On each iteration want to get a print to see what was the last inserted item.
The Code :
INSERT INTO [tData2]
(
[Key],
Info1,
Info2
)
SELECT
[Key], --the Id
Info1,
Info2
FROM
[tData]
Edit :
(There were other conditions to limit the insertion, which aren't related to the question)
The Bulk-Insertion logic will not be changed, just we shrink the database pieces to be inserted.
Instead of inserting the whole table we Bulk-Insert 10000 items per iteration and could get a simple report on it also.
your help is really appreciated.
Here's some sample code I quickly put together for you to experiment with. This doesn't use a cursor (uses while instead) but you could build it that way as well. There are some performance optimizations that you could make but only you can judge that. YMMV
set nocount on
/* mock up source/dest tables */
declare #src table (id int, value varchar(max));
declare #dest table (id int, value varchar(max));
/* fill source with some data */
declare #rownum int;
set #rownum=0;
while (#rownum<5000) begin
insert into #src select #rownum,'test value ' + CONVERT(varchar(25),#rownum);
select #rownum=#rownum+1;
end
/* laod batched data */
declare #pagesize int;set #pagesize=1000;
declare #rowlow int;set #rowlow=0;
declare #rowmax int;set #rowmax=#pagesize;
declare #ct int;select #ct = COUNT(*) from #src;
declare #id int;
declare #value varchar(max);
while (#rowmax<=#ct) begin
WITH result_set AS (
SELECT ROW_NUMBER() OVER (ORDER BY id) AS [row_number], id,value
FROM #src
) insert into #dest
SELECT id,value FROM result_set
WHERE [row_number] BETWEEN #rowlow AND #rowmax
-- Output
print 'Copied rows ' + convert(varchar(25),#rowlow) + ' to ' + convert(varchar(25),#rowmax)
-- Increment batch counters
select #rowlow=#rowmax+1,#rowmax+=#pagesize;
end
select * from #dest