Update SQL Server table rows with sequential numbers - sql

I have a SQL Server table in the below format and I am looking for a solution to keep the QuestionOrder in the correct sequence for that QuestionnaireID when I delete a record from this table. So let's say I delete the row with ID = 3, the QuestionOrder column for all rows with QuestionnaireID = 1 will be updated to be in the right sequence starting from 1 to N.
ID
QuestionnaireID
Question
QuestionOrder
...
1
1
Question-1
1
...
2
1
Question-2
2
...
3
1
Question-3
3
...
4
1
Question-4
4
...
5
1
Question-5
5
...
6
2
Question-1
1
...
7
2
Question-2
2
...

Try this, assuming your table's name is QuestTable.
First create the stored procedure:
CREATE PROCEDURE dbo.usp_QuestionOrder_DeleteAndReOrder
#QuestionnaireID int,
#QuestionOrder int
AS
BEGIN
SET NOCOUNT ON;
DELETE
FROM QuestTable
WHERE QuestionnaireID = #QuestionnaireID
AND QuestionOrder = #QuestionOrder;
UPDATE QuestTable
SET QuestionOrder = QuestionOrder - 1
WHERE QuestionOrder > #QuestionOrder;
END
Then make the call:
DECLARE #QuestionnaireID int = 1,
#QuestionOrder int = 3;
EXEC dbo.usp_QuestionOrder_DeleteAndReOrder
#QuestionnaireID, #QuestionOrder;
SELECT *
FROM QuestTable

Related

How do u use between operator for range?

This is my table Data
Id Begin End
1 0 1
2 1 3
3 3 4
This is my Query:
DECLARE #abc Float=1.5;
SELECT * FROM dbo.Slab AS s WHERE #abc BETWEEN s.Begin AND s.End
This give me 2 rows. I want to find a row for which #abc parameter is greater than Begin but less or equal to End.For example if #abc=1 i want to select 1 , if #abc=1.5 I want to select 2 , if #abc=3 i want to select 2 , if #abc=0.1 i want to select 1 and so on.
DECLARE #abc Float=1.5;
SELECT * FROM dbo.slab AS s WHERE #abc > s.[begin] and #abc<=s.[end]

Fill multiple empty rows

I'm tryting to fill empty rows from my table . Here is the example from my table.
ID | Code |
1 NULL
2 NULL
3 NULL
what i want is
ID | Code |
1 KL0000001
2 KL0000002
3 KL0000003
I'm using sql server 2008 and here is my script so far :
declare #jml as int;
declare #no as int = 1;
declare #kode as varchar(50);
set #jml = (SELECT COUNT(IdArealeader) FROM arealeader);
set #kode = (select case
when right(max(KodeareaLeader),7) is null then 'KL0000001'
else ('KL' + RIGHT('0000000' + cast(right(max(KodeareaLeader),7) + 1 as nvarchar),7))
end KodeareaLeader from arealeader)
while #no < #jml begin
update arealeader set KodeareaLeader = #kode;
END
Try this simple method,
UPDATE T
SET T.Code = 'KL'+REPLICATE('0',7 - LEN(ID))+CAST(ID AS NVARCHAR(10))
FROM test_table T
Try to avoid loops, only use if it necessary.
Result
ID Code
1 KL0000001
2 KL0000002
3 KL0000003
....
10 KL0000010

Sorting results of SQL query just like IN parameter list

I'm doing a query which looks something like
SELECT id,name FROM table WHERE id IN (2,1,4,3)
I'd like to get
id name
2 B
1 A
4 D
3 C
but I'm getting
1 A
2 B
3 C
4 D
Is there any way to sort the query results in the same way as the list I'm including after IN?
Believe me, I have a practical reason that I would need it for ;)
SELECT id,name FROM table WHERE id IN (2,1,4,3)
ORDER BY CASE id
WHEN 2 THEN 1
WHEN 1 THEN 2
WHEN 4 THEN 3
WHEN 3 THEN 4
ELSE 5
END
This might solve your problem.
Solution 2, insert your list into a temp table and get them a running sequence
id, seq(+1 every new row added)
-----------------
2 1
1 2
4 3
3 4
then join 2 table together and order by this seq.
Okay, I did it myself. It's a bit mad but it works ;)
DECLARE #IDs varchar(max)
DECLARE #nr int
DECLARE #znak varchar(1)
DECLARE #index int
DECLARE #ID varchar(max)
SET #IDs='7002,7001,7004,7003'
SET #nr=1
SET #index=1
IF OBJECT_ID('tempdb..#temp') IS NOT NULL DROP TABLE #temp
CREATE TABLE #temp (nr int, id int)
--fill temp table with Ids
WHILE #index<=LEN(#Ids)
BEGIN
set #znak=''
set #ID=''
WHILE #znak<>',' AND #index<=LEN(#Ids)
BEGIN
SET #znak= SUBSTRING(#IDs,#index,1)
IF #znak<>',' SET #ID=#ID+#znak
SET #index=#index+1
END
INSERT INTO #temp(nr,id) VALUES (#nr,CAST(#ID as int))
SET #nr=#nr+1
END
-- select proper data in wanted order
SELECT MyTable.* FROM MyTable
INNER JOIN #temp ON MyTable.id=#temp.id
ORDER BY #temp.nr

Loop for each row

I have two tables with FOREIGN KEY([Table_ID])
Columns
ID Table_ID ActiveFlag
1 1 0
2 2 1
3 1 1
4 3 0
Sys_Tables
Table_ID Name
1 Request
2 Plan
3 Contecst
I'm writing a stored procedure that returns any column for each table.
Example Output for values ​​above
--first output table
ID Table_ID ActiveFlag
1 1 0
3 1 1
--second output table
ID Table_ID ActiveFlag
2 2 1
--third output table
ID Table_ID ActiveFlag
4 3 0
My idea is this
Select c.*
from Ccolumns c
inner join Sys_tables t
on t.Table_ID = c.Table_ID and t.Table_ID = #Parameter
My problem, i do't know how to make a loop for each row. I need the best way. Example i can use following loop:
DECLARE #i int = 0
DECLARE #count int;
select #count = count(t.Table_ID)
from Sys_tables t
WHILE #i < #count BEGIN
SET #i = #i + 1
--DO ABOVE SELECT
END
But this is not entirely correct. Example my Sys_tables such data may be
Table_ID Name
1 Request
102 Plan
1001 Contecst
Do You have any idea?
There are couple ways you can achieve that: loops and cursors, but first of all you need to know that it's a bad idea: either are very slow, anyway, here's some kind of loop sample:
declare #row_ids table (
id INT IDENTITY (1, 1),
rid INT
);
insert into #row_ids (rid) select someIdField from SomeTable
declare #cnt INT = ##ROWCOUNT
declare #currentRow INT = 1
WHILE (#currentRow <= #cnt)
BEGIN
SELECT rid FROM #row_ids WHERE id = #currentRow
SET #currentRow = #currentRow + 1
END
I guess you're using SQL Server, right?
Then, you can use a CURSOR as here: How to write a cursor inside a stored procedure in SQL Server 2008

Inserts and Updates in SQL Server for a stored procedure

I have a table like this in SQL Server:
varID(PK) dataID(PK) is_used
A 1 0
B 1 0
Then I'm loading data to update is_used to 1 if the varID/dataID combo exists and add it in otherwise.
So I have to insert/update these varID/dataID combos.
varID(PK) dataID(PK)
B 1
C 1
So the updated table would look like this:
varID(PK) dataID(PK) is_used
A 1 0
B 1 1
C 1 1
What's the easiest way to do this? I will do it in a stored procedure.
Procedure tries to update is_used given a key. If unsuccessful, inserts new row. Note I put 0 as default value for is_used - I think is_used = 1 for (C, 1) is an inadvertence.
create proc AddVarDataCombo (#varID varchar(100), #dataID int)
as
set nocount on
update ATable
set is_used = 1
where varID = #varID
and dataID = #dataID
if ##rowcount = 0
begin
insert into ATable
values (#varID, #dataID, 0)
end