Is it possible to use ActiveRecord's update_all function to create a MySQL query like:
UPDATE `key_value_store`
SET `key` =
CASE `key`
WHEN 'xxxxxxx' THEN 'yyyyyyyy'
WHEN 'zzzzzzz' THEN 'wwwwwwww'
...
END
WHERE `key` IN ('some key', 'some other key', ...)
LIMIT 1000
What I have now is
keys = ['some key', 'some other key', ...]
Keyvaluemodel.where(:key => keys).limit(1000).update_all()
So the question is really, what code goes in the update_all brackets so this update works the way I want it?
This isn't possible unless you write some raw SQL or a custom query. But considering that you only have two cases, it's easy enough to write two queries.
If you look at the docs you will see that the only parameter update_all accepts is the SET part of the SQL query.
updates - A string, array, or hash representing the SET part of an SQL statement.
So either write a custom query, or split the update into several queries, one for each CASE.
Model.where(key: key_1).limit(1000).update_all(key: new_key)
Model.where(key: key_2).limit(1000).update_all(key: new_key)
use key-value pair in the parameter like:
Keyvaluemodel.where(:key => keys).limit(1000).update_all(:key=>'new key')
Related
I'm trying to pass data from a Webscraper to a MySQL database. I have a lot of variables that need to be entered at a time into the database and below is a snippet of the code I'm using. (where the etc. is there are a bunch more variables.
con.query(INSERT INTO Paper_2 (referenceCodeSubject,referenceCode,subject, etc.) values ('"+referenceCodeSubject+"','"+referenceCode+"','"+subject+"', etc.))
The columns in the database have types INT, VARCHAR and CHAR.
My issue is that when I scrape not all of the variables will be assigned values and will remain as 'null' and I cannot pass this null as NULL to MySQL. It would also be quite complicated to sort the different cases for when to pass what due to the large amount of variables.
I'm hoping theres a simple way of doing this as the only solutions I've seen so far are omit the value in the query (which is hard because I would then need to decide which values to omit) or pass a string of "NULL" or just a value of 0. Is there any other way of doing this?
Better use the built in escaping feature to avoid sql injection attacks!
conn.query(
'INSERT INTO Paper_2 (referenceCodeSubject,referenceCode,subject) VALUES ?'
[
['refCodeSubject1', 'refCode1', 'subject1'],
['refCodeSubject2', 'refCode2', null]
],
(error, results, fields) => {
...
}
)
If you have the case, that the bind values can sometime be a valid string and sometimes undefined, use an or operator in sqlValues to handle both cases with shorthand code:
let nameValue;
let sql="insert into user (name) values (?)"
let sqlValues[] = [nameValue || null ]
I want to set the condition which shows all vehicles where the title_recieved is null.
->andFilterWhere(['=', 'tr.title_recieved', null])
->andFilterWhere(['is', 'tr.title_recieved', null])
->andFilterWhere(['is', [ 'tr.title_recieved', null]])
I've tried all the available options, the is null condition works in andWhere, but not in andFilterWhere.
Use andWhere on query liek this.
->andWhere(['tr.title_recieved' => null]);
Try With This :
->andFilterWhere('tr.title_recieved is NULL');
**As per yii2 doc
andFilterWhere() Adds an additional WHERE condition to the existing one but ignores empty operands.
The new condition and the existing one will be joined using the 'AND' operator.
This method is similar to andWhere(). The main difference is that this method will remove empty query operands. As a result, this method is best suited for building query conditions based on filter values entered by users.
From doc http://www.yiiframework.com/doc-2.0/yii-db-querytrait.html#andFilterWhere()-detail **
It can be done like this
$query->andFilterWhere(['IS', 'tr.title_recieved', new \yii\db\Expression('NULL')]);
I have a problem in using Rails / ActiveRecord.
I want to insert record with MySQL function, for example GeomFromText('POINT(1 1)').
Using ActiveRecord normally, these functions are quoted automatically. I want not to quote these values.
Model.create(geo: GeomFromText('POINT(1 1)'))
this ActiveRecord statement will generate following SQL
INSERT INTO `Model` (`geo`) VALUES ('GeomFromText(\'POINT(1 1)\')')
It may be easy to use raw SQL, but I want to use ActiveRecord because my Model set several callbacks include self table.
How can use MySQL function with ActiveRecord statement?
Summary
You can't by design; this behavior is important for preventing SQL injection attacks. You would need to explicitly execute raw SQL in conjunction with ActiveRecord.
Details
As you saw, the SQL statement gets interpolated as a string by design, which doesn't do what you want (Rails ~> 4.0):
> Country.create(name: 'LOWER("CANADA")')
=> SQL (0.3ms) INSERT INTO `Country` (`Name`) VALUES ('LOWER(\"CANADA\")')
Nor can you use the same tricks that would work for the .where method:
> Country.create(["name = LOWER(:country)", { country: 'CANADA' }])
=> ArgumentError: When assigning attributes, you must pass a hash as an argument.
You would need to execute arbitrary SQL first to get the proper value, then make another SQL call via ActiveRecord to achieve your callback:
> Country.create( name: ActiveRecord::Base.connection.execute(%q{ SELECT LOWER('CANADA') }).first[0] )
=> (0.3ms) SELECT LOWER('CANADA')
=> SQL (0.3ms) INSERT INTO `Country` (`Name`) VALUES ('canada')
That said, it's probably cleaner to re-implement the SQL function at the application layer instead of the DB layer (unless you've got a really complex SQL function).
$xyz = mysql_fetch_array(mysql_query('select sum(value) points where userId = $userIdDB'))['suma'];
How that query will looks in zend framework? I need to select sum of records from DB as int.
And another question: can i make mysql queries. I dont have in real any knowledge from zend, so I please for full explanation.
What about mysql connections in zend?
In ZEND
$select = $db->select()
->from('points',array(new Zend_Db_Expr('sum(value)')))
->where('userId = ?', $userIdDB);
When Adding Expression Columns
Columns in SQL queries are sometimes expressions, not simply column
names from a table. Expressions should not have correlation names or
quoting applied. If your column string contains parentheses,
Zend_Db_Select recognizes it as an expression.
You also can create an object of type Zend_Db_Expr explicitly, to
prevent a string from being treated as a column name. Zend_Db_Expr is
a minimal class that contains a single string. Zend_Db_Select
recognizes objects of type Zend_Db_Expr and converts them back to
string, but does not apply any alterations, such as quoting or
correlation names.
EXAMPLE IN ZEND
// Build this query using Zend_Db_Expr explicitly:
// SELECT p."product_id", p.cost * 1.08 AS cost_plus_tax
// FROM "products" AS p
$select = $db->select()
->from(array('p' => 'products'),
array('product_id',
'cost_plus_tax' =>
new Zend_Db_Expr('p.cost * 1.08'))
);
How does one properly update a mysql field with a NULL value when using a variable in the sql query?
I have a variable called $timestamp. When it's set to date( Y-m-d h:i:s ) I have to wrap it in quotes because I'm passing a string in my mysql query. When $timestamp is set to NULL, the database query contains '' as the value for $timestamp and the field updates to 0000-00-00 00:00:00. It's important to keep this field as NULL to show that the process has never been run before.
I don't want to use now() because then my sql statement is not in sync with my class variable $timestamp.
I don't want to set $timestamp to 'NULL' because then that variable is not accurate. It's no longer NULL, it's set to a string that contains the word NULL.
What am I missing here?
The correct SQL syntax to set a column to NULL is:
UPDATE Table SET Column = NULL WHERE . . .
(note the lack of quotes around the literal NULL).
Are you performing this UPDATE using SQL or using some kind of framework? If a framework, it should recognize NULL values and pass them to the database correctly for you.
After a lot of research, I've found that this is a well known problem with no good solution if you are writing your sql queries outright.
The correct solution is to use a database abstraction layer like PDO ( for PHP ), or Active Record ( used in frameworks like Codeignitor and Ruby on Rails ).