Construct CDbCriteria with column names as MySQL reserved words - yii

I have exactly the same problem like in this question (attempt to use CDbCriteria with column named key, which is a reserved word in MySQL). However, provided solution:
$criteria = new CDbCriteria;
$criteria->condition = 't.key=:key';
$criteria->params = array(':key'=>$this->key);
$criteria->compare('position', $this->position);
$criteria->compare('dictionary', $this->dictionary);
works for me only partially. I don't get exception anymore, but search works for key column only. All other are ignored (if key is set, respects only this value in search, if it is not set -- always returns empty results set).
What am I missing? How should I construct CDbCriteria queries, when my table contains reserverd words as column names, so search would respect all other (non-reserved) columns as well, not only this one?

CDbCriteria::compare() adds condition only if parameter is set otherwise no action is taken.See Here
$criteria->condition = 't.key=:key';
$criteria->params = array(':key'=>$this->key);
However this logic works irrespective of whether key is set or not. So basically your condition becomes
SELECT * FROM `some_table` t WHERE t.key =:key
even though the key value being blank resulting in your query breaking when key attribute is not set
So if you modify your statement like this then it work
if(isset($this->key){
$criteria->condition = 't.key=:key';
$criteria->params = array(':key'=>$this->key);
}
in this case this statement is only activated when key attribute is set, it is ignored otherwise, and your query will not break

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.

update a column using values from a different column of the same table

Given the DB table:
CREATE TABLE stuff (
id text not null,
other text
);
That has lots of id values but has all other set to NULL, is there an elegant way to update the table so that all other rows get updated to OTHER-{id} (where {id} is the value of the id column)?
(It must work in Postgresql)
Only a simple update statement is needed with some string concatenation (||):
update stuff
set other = 'OTHER-' || id
You'll want to use the following:
UPDATE stuff
SET other = 'OTHER-' || id;
UPDATE is the keyword used to identify which table you'd like to update.
SET is the keyword used to identify which column you'd like to update, and this is where you choose to assign the column to:
'OTHER-' || id
'OTHER-' being a string
|| a shorthand way to concatenate
id the value you want.
Another way of writing this would be
other = concat('OTHER-',id);
I along with many others will find the || method to be much cleaner, but it's worth knowing about the dedicated function as well.

SQL WHERE is anything

I'm working on a database query via a search bar and would like it to sometimes yield all results (depending on what is inputted)
I know that for SELECT you can use * in order to select all columns. Is there similar SQL syntax: i.e. WHERE name IS * to essentially always be true?
Edit to clarify:
The nature of the clause is that a variable is used to set the name (I'm actually not able to change the clause, that was made clear). i.e. WHERE name IS [[inputName]] (inputName is the decided by the search bar)
WHERE ISNULL(name, '') = ISNULL(name, '')
(assuming that 'name' is of a string type)
Just make the column reference itself. However, if this is the only goal of your query, why are you against omitting the WHERE clause?
If you want to return all results in a SQL statement, you can simply omit the WHERE clause:
SELECT <* or field names> FROM <table>;
You should use WHERE only when you want to filter your data on a certain field. In your case you just don't want to filter at all.
Actually you don't need WHERE clause at all in this situation. But if you insist then you should write your predicate so it always returns true. This can be done many ways:
Any predicate like:
WHERE 1=1
With column:
WHERE name = name OR name is null
With LIKE:
WHERE name LIKE '%' OR name is null
With passed parameter:
WHERE name = #name OR #name is null
You can think of more of course. But I think you need the last one. Pass NULL from app layer if you want all rows.

SQL UPDATE with Multiple ANDs

I'm receiving the error
An expression of non-boolean type specified in a context where a condition is expected, near 'location'
when running this query:
UPDATE dbo.table
SET name = 'Matt'
WHERE date = '2013-11-23'
AND time = '12:57'
AND location = 'London'
If I modify the query to remove any one of the ANDs the query works.
Two questions:
Is it not possible to have more than one AND in the WHERE condition for an UPDATE?
How do I structure the query to make it work?
Thanks
It could be the use of reserved words like time and date. Try putting [] around those names and see if it works. And more importantly, you should use better names for your columns instead of those reserved words.

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.