Update row with multiple columns - sql

So I want to be able to update a row in my table. I know how to do this
UPDATE Param
SET(Param1=#Param1, Param2=#Param2, Param3=#Param3, ...)
WHERE ParamId = #ParamId
The problem is that I don't know which column will be updated and which isn't, it depends on what the user changed. And I have a lot of param to to check.
--idk if this will work, I am just trying to limit the amont of code posted
ISNULL(#Param1, Select Param1 from Param where WHERE ParamId = #ParamId)
I was thinking about dynamic SQL, but it poses to much of a security risk. Is there a way for me to do this faster? Or is there no way around this? If you need more info please ask.

You could use COALESCE/ISNULL but you don't need to select the old value as default as sub query, you can use it directly:
UPDATE Param
SET Param1=COALESCE(#Param1,Param1), Param2=COALESCE(#Param2,Param2), ...
WHERE ParamId = #ParamId
However,on this way you cannot set a nullable column to NULL. I assume this is desired.

Related

SQL expression for not changing the field in UPDATE?

It must be a classic scenario, but I don't see any question for it...
I receive a lot of arguments in HTTP request for updating a row in the database.
Some other parameters are not set.
I am using some C++ framework for the SQL queries.
And I have a query like:
auto update(R"__(
UPDATE
table
SET
field1 = ?,
field2 = ?
WHERE
id = ?
)__");
exec_update(update, {field1.value_or(<?>), field2.value_or(<?>), id})
Because there can be around 30 fields to update, I don't want to create the query dynamically, but I would rather use some keyword to tell the Postgresql not to change the fields that I don't have new value for, how to achieve that?
Simply, what to put instead of the <?>?
I only found a similar question: How do I update selective fields in SQL (leaving some unchanged)?, which is a special case for this, I want to be able to set even NULL or whatever, I just want to not update some fields from the query without changing the query, I want to just have the values dynamic, not the query.
EDIT: I couldn't find anything better than having the dynamic query like:
auto update(fmt::format(
R"__(
UPDATE
table
SET
field1 = {},
field2 = {},
WHERE
id = {}
)__",
object.get_field1().has_value() ? fmt::format("'{}'", object.get_field1().value())
: "field1",
object.get_field2().has_value() ? fmt::format("'{}'", object.get_field2().value())
: "field2",
id));
, but I am not much satisfied with that.

Oracle Update table to set specific attribute value in semicolon separated values

I have a column where I have values like:
Email_Password+oi8hu907b;New_eMail+Y;Email_Username+iugbhijhb8
Now I want to update New_eMail attribute for all rows which has Y to N without affecting anything else.
Please advise.
i hate it but...
update table
set column = replace(column,'New_eMail+Y','New_eMail+N')
where column like '%New_eMail+Y%'
you don't need the WHERE clause but if you put a functional index on the table it may be quicker with it
Since it may be the only place in the string where '+Y;' occurs the following statement may do the trick:
update <your_table>
set <your_column> = replace(<your_column>,'+Y;','+N;')
where instr(<your_column>,'+Y;')>0
This solution differs from the others provided because it does not depend on the value of the email address.
My answer is a slight improvement over the answer from user davegreen100
Since they don't allow me to post it as a comment, I add it here.
update <<tablename>>
set <<columnname>> = replace(<<columnname>>,';New_eMail+Y;',';New_eMail+N;')
where <<columnname>> like '%;New_eMail+Y;%'

My SQL Update Statement updates even if the value is the same

I want to update a column value. But my Update procedure statement updates even the value of the this column is the same.
UPDATE TableName
SET ColumName=#ParameterName
WHERE Id=#ParameterId
Any Idea?
Thank you.
From what I get from your post, you are wondering why MySQL is updating even when the value is not changed. Well, you don't check beforehand if the value is really different, so that's just what an update statement with an ID does...
You can add additional condition AND (COALESCE(ColumName,'')<>COALESCE(#ParameterName,'')
so you're only updating when those are different.
UPDATE TableName
SET ColumName=#ParameterName
WHERE (Id=#ParameterId) AND (COALESCE(ColumName,'')<>COALESCE(#ParameterName,''))
The coalsece in my example assumes that ColumnName is of type varchar if is a numeric value use AND (COALESCE(ColumName,0)<>COALESCE(#ParameterName,0) instead.

Update A multi-valued field in Access

I have created a lookup table in Access to provide the possible values for a column. Now I need to update this column with the data it had before I converted the column. I am unable to figure out a SQL Query that will work. I keep getting the error "An UPDATE or DELETE query cannot contain a multi-valued field." My research has suggested that I just need to set the value of the column but this always updates 0 records:
UPDATE [table_name] SET [column_name].Value = 55 WHERE [table_name].ID = 16;
I know this query will work if I change it to update a text column, so it is definitely a problem with just this column.
If you're adding a value to your multi-valued field, use an append query.
INSERT INTO table_name( [column_name].Value )
VALUES (55)
WHERE ID = 16;
If you want to change one particular value which exists in your multi-valued field, use an UPDATE statement. For example, to change the 55 to 56 ...
UPDATE [table_name]
SET [column_name].Value = 56
WHERE [column_name].Value = 55 And ID = 16;
See Using multivalued fields in queries for more information.
I have figured this out! It certainly was counter-intuitive! You have to use an INSERT statement to do the update.
-- Update a record with a multi-valued field that has no value
INSERT INTO [table_name] ( [[column_name].[Value] )
VALUES(55)
WHERE [table_name].ID = 16;
This confused me because I was expecting an UPDATE statement. I think it actually inserts a record into a hidden table that is used to associate multiple values with this column.
I am working with Sharepoint, I created the tables as multi-value fields, ran into the error with my INSERT INTO statement, went back to Sharepoint to change to non-multi-value fields, but that didn't fix it.
Recreated the table without using multi-value fields, and the INSERT INTO worked just fine.
do not use the .value part
UPDATE [table_name] SET [column_name] = 55 WHERE [table_name].ID = 16;
INSERT INTO Quals (cTypes.[value])
SELECT Quals_ContractTypes.ContractType
FROM Quals_ContractTypes
WHERE (Quals.ID = Quals_ContractTypes.ID_Quals);
I gotta say I didn't understand very well your problem but I saw something strange in your query. Try this:
UPDATE [table_name] SET [column_name]= 55 WHERE [table_name].ID = 16;
UPDATE:
Look at this link: it has an example
UPDATE Issues
SET Issues.AssignedTo.Value = 10
WHERE (((Issues.AssignedTo.Value)=6)
AND ((Issues.ID)=8));
NOTES
You should always include a WHERE
clause that identifies only the
records that you want to update.
Otherwise, you will update records
that you did not intend to change. An
Update query that does not contain a
WHERE clause changes every row in the
table. You can specify one value to
change.
The Multi-Valued field refers to Access databases that have tables with columns, that allow you to select multiple values, like a Combo Checkbox list.
THOSE are the only Access types that SQL cannot work with. I've tested all Access lookup possibilities, including hard-coded values, and lookup tables. They work fine, but if you have a column that has the Allow Multiple select options, you're out of luck. Even using the INSERT INTO as mentioned below, will not work as you'll get a similar but different error, about INSERTing into multi-valued fields.
As mentioned it's best to avoid using such tables outside of Access, and refer to a table specifically for your external needs. Then write a macro/vba script to update the real tables with the data from the "auxiliary" table.

Dynamic Query in SQL Server

I have a table with 10 columns as col_1,col_2,.... col_10. I want to write a select statement that will select a value of one of the row and from one of these 10 columns. I have a variable that will decide which column to select from. Can such query be written where the column name is dynamically decided from a variable.
Yes, using a CASE statement:
SELECT CASE #MyVariable
WHEN 1 THEN [Col_1]
WHEN 2 THEN [Col_2]
...
WHEN 10 THEN [Col_10]
END
Whether this is a good idea is another question entirely. You should use better names than Col_1, Col_2, etc.
You could also use a string substitution method, as suggested by others. However, that is an option of last resort because it can open up your code to sql injection attacks.
Sounds like a bad, denormalized design to me.
I think a better one would have the table as parent, with rows that contain a foreign key to a separate child table that contains ten rows, one for each of those columns you have now. Let the parent table set the foreign key according to that magic value when the row is inserted or updated in the parent table.
If the child table is fairly static, this will work.
Since I don't have enough details, I can't give code. Instead, I'll explain.
Declare a string variable, something like:
declare #sql varchar(5000)
Set that variable to be the completed SQL string you want (as a string, and not actually querying... so you embed the row-name you want using string concatenation).
Then call: exec(#sql)
All set.
I assume you are running purely within Transact-SQL. What you'll need to do is dynamically create the SQL statement with your variable as the column name and use the EXECUTE command to run it. For example:
EXECUTE('select ' + #myColumn + ' from MyTable')
You can do it with a T-SQl CASE statement:
SELECT 'The result' =
CASE
WHEN choice = 1 THEN col1
WHEN choice = 2 THEN col2
...
END
FROM sometable
IMHO, Joel Coehoorn's case statement is probably the best idea
... but if you really have to use dynamic SQL, you can do it with sp_executeSQL()
I have no idea what platform you are using but you can use Dynamic LINQ pretty easily to do this.
var query = context.Table
.Where( t => t.Id == row_id )
.Select( "Col_" + column_id );
IEnumerator enumerator = query.GetEnumerator();
enumerator.MoveNext();
object columnValue = enumerator.Current;
Presumably, you'll know which actual type to cast this to depending on the column. The nice thing about this is you get the parameterized query for free, protecting you against SQL injection attacks.
This isn't something you should ever need to do if your database is correctly designed. I'd revisit the design of that element of the schema to remove the need to do this.