My aim is to update some records with range of numbers (4987-4993) the first record should be with the number 4987 the next 4988..etc' and when the loop condition is #a=4993 it should stop, I tried using SQL cursor but I updated every thing with the same number (4992).... what am I missing?
DECLARE #a AS INT;
DECLARE #b AS INT;
select #a = 4987
declare myCursor cursor for
select modelcode from model
where try_cast(modelcode as int) > 1600 and try_cast(modelcode as int) <1700
open myCursor
fetch next from myCursor into #b
while #a < 4993
begin
update model
set ModelCode = #a
where try_cast(modelcode as int) < 1659
select #a = #a+1
fetch next from myCursor into #b
end;
close myCursor
DEALLOCATE myCursor;
Your update statement is independent from #b. You need to do something like this:
update model
set ModelCode = #a
where modelcode = #b;
Related
I got a table of words to be searched in the database and the table
Parameter
id Name Word
----------------------------------
1 word search c&a
2 word search Beton
3 word search Freiman
4 Anything Null
beside that i have the Procedure SearchAllTable, which is the searching Procedure and for searching the words in the database.
DECLARE #id int
DECLARE #name varchar(100)
DECLARE #word varchar(100)
DECLARE cur CURSOR FOR SELECT Id, word FROM #Parameter WHERE Name = 'word search'
OPEN cur
FETCH NEXT FROM cur INTO #id,#word
WHILE ##FETCH_STATUS = 0 BEGIN
EXEC SearchAllTables #word
FETCH NEXT FROM cur INTO #id, #word
END
CLOSE cur
DEALLOCATE cur
the problem that I got the result in multipule tables and I want them all to be listed in one table without any suppuration.
Insert your results into temporary table, created before cursor cycle
UPDATE
try this UNION the results of multiple stored procedures
Collect your result into a temp table or table variable and get it in a single select outside the cursor. Please try the bellow.
DECLARE #id int
DECLARE #name varchar(100)
DECLARE #word varchar(100)
--Create Result table wrt your SP output
DECLARE #Result TABLE (NAME VARCHAR(16), DATEVAL DATETIME)
DECLARE cur CURSOR FOR SELECT Id, word FROM #Parameter WHERE Name = 'word search'
OPEN cur
FETCH NEXT FROM cur INTO #id,#word
WHILE ##FETCH_STATUS = 0
BEGIN
INSERT INTO #Result
EXEC SearchAllTables #word
FETCH NEXT FROM cur INTO #id, #word
END
CLOSE cur
DEALLOCATE cur
--Selecting result as a single unit
SELECT * FROM #Result
Here is a simple example:
Why does this work:
DECLARE #v as varchar(75)
SET #v = 'xxx-xxxx'
SELECT * FROM tbl_skus WHERE SKU = #v
But this does not work:
DECLARE #v as varchar(75)
SET #v = 'xxx-xxxx,yyy-yyyy'
SELECT * FROM tbl_skus WHERE SKU IN ( #v )
Both SKUs 'xxx-xxxx' and 'yyy-yyyy' are in the table. The first query pulls 1 result, and the second pulls 0 results; no errors.
Because your query is looking for the literal 'xxx-xxxx,yyy-yyyy', it means that it's just one string, with a comma in it, not 2 strings separated by a comma.
Your query translates to:
SELECT * FROM tbl_skus WHERE SKU IN ('xxx-xxxx,yyy-yyyy')
And for it to work as you want, it shoul be:
SELECT * FROM tbl_skus WHERE SKU IN ('xxx-xxxx','yyy-yyyy')
You cannot assign two values to a single variable. You will have to do something like this:
DECLARE #v as varchar(75)
DECLARE #a as varchar(75)
SET #v = 'xxx-xxxx'
SET #a = 'yyy-yyyy'
SELECT * FROM tbl_skus
WHERE SKU IN (#v, #a)
You should use a cursor like this (for example):
DECLARE #MyCursor CURSOR
SET #MyCursor = CURSOR FAST_FORWARD
FOR
SELECT Table_Training_Detalis.DateExpires,Table_Training_Detalis.Worker_ID
FROM Table_Courses
OPEN #MyCursor
FETCH NEXT FROM #MyCursor
INTO #ColExpir,#ColWorkid
WHILE ##FETCH_STATUS = 0
BEGIN
update Table_Workers set WHIMIS= #ColExpir where Worker_ID=#ColWorkid
FETCH NEXT FROM #MyCursor
INTO #ColExpir,#ColWorkid
END
CLOSE #MyCursor
DEALLOCATE #MyCursor
I want to use cursor to delete record from table. How can I do it?
I use MSSQL 2008 Express this code does not delete anything from #temp. I also tried where current of cursor_name did not work.
Here is my sample code:
use AdventureWorks
drop table #temp
select * into #temp from HumanResources.Employee;
declare #eid as int;
declare #nid as varchar(15);
DECLARE Employee_Cursor CURSOR FOR
SELECT A.EmployeeID, A.NationalIDNumber FROM #temp AS A
OPEN Employee_Cursor;
FETCH NEXT FROM Employee_Cursor INTO #eid , #nid ;
WHILE ##FETCH_STATUS = 0
BEGIN
IF (#eid > 10)
BEGIN
delete from #temp where #temp.EmployeeID = #eid;
END
FETCH NEXT FROM Employee_Cursor;
END;
CLOSE Employee_Cursor;
DEALLOCATE Employee_Cursor;
GO
select * from #temp
thanks in advance
use AdventureWorks
select * into #temp from HumanResources.Employee;
declare #eid as int;
declare #nid as varchar(15);
DECLARE Employee_Cursor CURSOR FOR
SELECT A.EmployeeID, A.NationalIDNumber FROM #temp AS A
OPEN Employee_Cursor;
FETCH NEXT FROM Employee_Cursor INTO #eid , #nid ;
WHILE ##FETCH_STATUS = 0
BEGIN
IF (#eid > 10)
BEGIN
delete from #temp where current of Employee_Cursor
END
FETCH NEXT FROM Employee_Cursor INTO #eid , #nid ;
END;
CLOSE Employee_Cursor;
DEALLOCATE Employee_Cursor;
select * from #temp
drop table #temp
this works for me
There is a much simpler answer - use this command:
delete from HumanResources.Employee where current of Employee_Cursor
It's called 'Positioned delete' and described at MSDN.
Could you please try in below ways, thanks for your time.
You have fetched data from cursor but didn't push into your variables missed in WHILE loop, please have a look on below code, thanks.
drop table #temp
select * into #temp from Employee;
declare #eid as int;
declare #nid as varchar(15);
DECLARE Employee_Cursor CURSOR FOR
SELECT A.EmployeeID, A.NationalIDNumber FROM #temp AS A
OPEN Employee_Cursor;
FETCH NEXT FROM Employee_Cursor INTO #eid , #nid ;
WHILE ##FETCH_STATUS = 0
BEGIN
IF (#eid > 10)
BEGIN
delete from #temp where #temp.EmployeeID = #eid;
END
FETCH NEXT FROM Employee_Cursor INTO #eid , #nid ;
END;
CLOSE Employee_Cursor;
DEALLOCATE Employee_Cursor;
GO
select * from #temp
Update:
I've changes in 2nd FETCH statement, just have added below highlighted part, thanks
FETCH NEXT FROM Employee_Cursor INTO #eid , #nid ;
I'm very new to SQL Server. I'm using a cursor to populate a table with ids; I just discovered cursors today. The code is running but it is populating each row with the start value.
SET NOCOUNT ON
DECLARE #Irow int
declare #cheese int;
set #cheese = (select (max(balanceid) + 1) from balancetbl)
DECLARE aurum CURSOR FOR
SELECT #Irow
FROM aurumaugupload
OPEN aurum
FETCH aurum INTO #Irow
WHILE ##Fetch_Status = 0
BEGIN
update aurumaugupload set balanceid = #cheese
set #cheese = #cheese + 1;
FETCH aurum INTO #Irow
END
CLOSE aurum
DEALLOCATE aurum
RETURN
I think it's a really basic error but I can't see it due to my inexperience.
UPDATE: thanks guys for your prompts answers. I got it working after nonnb's help. Here's the final code:
SET NOCOUNT ON
DECLARE #acc int
declare #start int;
set #start = (select (max(balanceid) + 1) from balancetbl)
DECLARE aurum CURSOR FOR
SELECT accountid
FROM aurumaugupload
OPEN aurum
FETCH aurum INTO #acc
WHILE ##Fetch_Status = 0
BEGIN
update aurumaugupload set balanceid = #start where accountid = #acc
set #start = #start + 1;
FETCH aurum INTO #acc
END
CLOSE aurum
DEALLOCATE aurum
RETURN
There are at least 2 bugs here:
Bug 1
DECLARE aurum CURSOR FOR
SELECT #Irow
FROM aurumaugupload
will select the same (unitialised) constant for every row of aurumaugupload
You need something like
SELECT Irow
FROM aurumaugupload
Bug 2 - You are updating all rows within the cursor. You need a where
update aurumaugupload set balanceid = #cheese
where IRow = #IRow;
set #cheese = #cheese + 1
Your update statement doesn't have a where clause, so you are updating every row each time.
Try this solution (if the sorting/update order doesn't matter):
SET NOCOUNT ON
DECLARE #Irow int
DECLARE #cheese int;
SET #cheese = (SELECT (MAX(balanceid) ) FROM balancetbl)
UPDATE aurumaugupload
set #cheese = balanceid = #cheese+1;
I have an select statement that returns a single row.
After that I have written a cursor as for me ##fetch_status is -1 it does not go inside the cursor only now
open cur_mkt
print #init
While (#init = 0)
Begin
fetch next from cur_mkt into
#Desc,
#Divisions
print ##fetch_status
if (##fetch_status =-1)
BREAK
Is there any way I can go inside the cursor,
please help me out.
It doesn't sound like you need a cursor (which you should try to avoid anyway). If you're determining the presence of a result you could do:
SELECT #Desc = Desc, #Divisions = Divisions
FROM YourTable
WHERE ID = 1
IF ( ##ROWCOUNT > 0 )
BEGIN
-- Row was found
END
So I would recommend not using cursors.
To directly answer the question, the way you use cursors/iterate round the results is as follows:
DECLARE #A INTEGER
DECLARE cur_mkt CURSOR FOR
SELECT 1 AS A
UNION ALL
SELECT 2 AS A
OPEN cur_mkt
FETCH NEXT FROM cur_mkt INTO #A
WHILE (##FETCH_STATUS = 0)
BEGIN
PRINT #A
FETCH NEXT FROM cur_mkt INTO #A
END
CLOSE cur_mkt
DEALLOCATE cur_mkt