Use case condition in stored procedure to update table - sql

I have an existing table in the database. I want to update a column value with 1 or 2 by making a condition on another column value of the same table and I want to do it with a script
Below is the stored procedure script which I wrote but it is not updating the table.
CREATE PROCEDURE [dbo].[updateDocumentCategory]
AS
BEGIN
UPDATE cmdocuments
SET docCategoryId = CASE
WHEN (docUploadable = 'Y') THEN 2
WHEN (docUploadable = 'N') THEN 1
END
END
Provided below is the sample data

This is a bit long for a column.
Indeed, it is not updating the table. How can I tell? If it did, then the value would be NULL, not 0.
This suggests that the problem is that the stored procedure is not being called. If that is the case, you can just update the table using the specified update statement.
However, if this is something that you really need to be consistent, I would suggest using a computed column:
ALTER TABLE cmdocuments ADD docCategoryId AS (
CASE WHEN docUploadable = 'Y' THEN 2
WHEN docUploadable = 'N' THEN 1
END);
This will ensure that docCategoryId has the correct value without having to update the table. Then the stored procedure won't even be needed.

Related

How to find affected rows, after an update in SQL

I have a table and a stored procedure. I use the stored procedure to update the table. There are some cursors in the stored procedure and the SP is updating the table. I want to get the rows updated by the stored procedure. I don't want to number of updated rows, I want just updated rows.
I created a temporary table to insert with updated rows but can't get the updated rows. How can I get?
I am using SQL Server.
If your RDBMS supports it, you can use update returning like this:
sql> update your_table
set your_field = 'my new value'
where other_field = 'your condition'
returning *; -- this returning will return a result set with the modified rows
-- you could also specify a list of columns here if you don't want
-- all fields returned
Using returning clause should work with PostgreSQL, Oracle, and others.
If you are using SQLServer (as you've just stated on your question update), you can use output:
sql> update your_table
set your_field = 'my new value'
output your_list_of_fields -- this is a comma separated list of the
-- columns you want to return
where other_field = 'your condition';
You could use the INSERTED and DELETED virtual or "psuedo" tables which are created for this purpose. In UPDATE statements the virtual tables are accessible using the OUTPUT clause. Here's an example
drop table if exists #t;
go
create table #t(col_x char(1));
insert #t values('a');
update #t
set col_x='b'
output inserted.col_x as new_val,
deleted.col_x as old_val;
new_val old_val
b a

data type change to bit after alter column

I code this query, but unfortunately, I got this error:
"Argument data type bit is invalid for argument 1 of substring
function."
My Stored Procedure is:
ALTER TABLE A ALTER COLUMN B nvarchar(20);
UPDATE A SET B = CASE WHEN SUBSTRING(B, 1, 2)>1000
THEN '1' + B ELSE B END
I convert my data but again get an error.
Absolutely my update query work if there is not the first one(Alter Table Alter Column).
Can anyone explaine why this occurred and how should I fix it?
This code works:
create table a (b bit);
alter table a alter column b nvarchar(20);
go
update a
set b = substring(b, 1, 2);
This code does not:
create procedure p as
begin
alter table a alter column b nvarchar(20);
update a
set b = substring(b, 1, 2);
end;
Why not? The first code actually changes the table, so the update is correct when it is run. Within the stored procedure, the two statements are compiled -- but not run. That means that the update is compiled, but the table has not changed. Hence you get an error.
Although you could solve this using dynamic SQL, I would instead ask why you are modifying column types in a stored procedure. That seems quite irregular. Normally, stored procedures do not do such modifications.
ALTER table Table_1
ALTER COLUMN Id NVARCHAR(20)
//Then continue...

Creating a dynamic trigger comparing all fields in Firebird

For updating a field called 'last_modified' I'm trying to update this field automatically using a trigger, in stead of changing all update-statements. The field should only be updated when a field value has changed. Problem here is that you have to maintain the triggers if a table field is added, removed or renamed. The fields are stored in rdb$relation_fields, no problem. But building a query comparing the old and new value dynamically is.
create trigger test for test_table active before update position 0 as
declare variable fn char(31);
begin
for select rdb$field_name from rdb$relation_fields where rdb$relation_name = 'test_table' into :fn do
begin
if ('old.'||:fn <> 'new.'||:fn) then
begin
new.last_modified = current_timestamp;
break;
end
end
end
Problem here is that 'old.'||:fn and 'new.':fn not really are comparing values, but literal strings, so the value of the fields cannot be compared. I've seen over here Firebird - get all modified fields inside a trigger that a trigger is attached to a system table, something I don't want to.
Is this fully-automated way of updating the 'last_modified' field not possible in this way? Or do I have to create a stored procedure that deletes al triggers and then recreates them with new fields, once I perform a update on the database (using this code http://www.firebirdfaq.org/faq133/).

SQL update if exist and insert else and return the key of the row

I have a table named WORD with the following columns
WORD_INDEX INT NOT NULL AUTO_INCREMENT,
CONTENT VARCHAR(255),
FREQUENCY INT
What I want to do is when I try to add a row to the table if a row with the same CONTENT exits, I want to increment the FREQUENCY by 1. Otherwise I want to add the row to the table. And then the WORD_INDEX in the newly inserted row or updated row must be returned.
I want to do this in H2 database from one query.
I have tried 'on duplicate key update', but this seems to be not working in H2.
PS- I can do this with 1st making a select query with CONTENT and if I get a empty result set, makeing insert query and otherwise making a update query. But as I have a very large number of words, I am trying to optimize the insert operation. So what I am trying to do is reducing the database interactions I am making.
Per your edited question .. you can achieve this using a stored procedure like below [A sample code]
DELIMITER $$
create procedure sp_insert_update_word(IN CONTENT_DATA VARCHAR(255),
IN FREQ INT, OUT Insert_Id INT)
as
begin
declare #rec_count int;
select #rec_count = count(*) from WORD where content = CONTENT_DATA;
IF(#rec_count > 0) THEN
UPDATE WORD SET FREQUENCY = FREQUENCY + 1 where CONTENT = CONTENT_DATA;
SELECT NULL INTO Insert_Id;
else
INSERT INTO WORD(CONTENT, FREQUENCY) VALUES(CONTENT_DATA, FREQ);
SELECT LAST_INSERT_ID() INTO Insert_Id;
END IF;
END$$
DELIMITER ;
Then call your procedure and select the returned inserted id like below
CALL sp_insert_update_word('some_content_data', 3, #Insert_Id);
SELECT #Insert_Id;
The above procedure code essentially just checking that, if the same content already exists then perform an UPDATE otherwise perform an INSERT. Finally return the newly generated auto increment ID if it's insert else return null.
First try to update frequency where content = "your submitted data here". If the affected row = 0 then insert a new row. You also might want make CONTENT unique considering it will always stored different data.

Need example of Conditional update stored proc in SQL server

I am just at starting levels in DB usage and have 2 basic questions
I have a generic UPDATE stored proc which updates all columns of a table.
But i need to make it conditional wherein it does not SET when the parameter is NULL.
Usage: I want to use this as a single SP to UPDATE any subset of columns, the caller from C# will fill in corresponding parameter values and leave other parameters NULL.
2
In case of , "UPDATE selected records" do i need to use locking inside stored proc ?
Why ? Isn't the operation in itself locked and transactional ?
I find the same question come up when i need to UPDATE selected(condition) records and then Return updated records.
UPDATE table
SET a = case when #a is null then a else #a end
WHERE id = #id
OR
EXEC 'update table set ' + #update + ' where id = ' + #id
OR
Conditionally update a column at a time
First option to me would usually be preferrable as it is usually efficient enough and you do not need to worry about string escaping
If I have understood the question properly, Why can't you build a query on the fly from sql server SP, and use sp_sqlexecute. So when you build query you can ensure only columns that have value has got updated.
Does this answer your question?