I'm triyng to create a column family with TimeUUIDType as name of row:
create column family users
with column_type = 'Standard'
and comparator = 'TimeUUIDType'
and default_validation_class = 'UTF8Type'
and key_validation_class = 'UTF8Type'
and memtable_operations = 0.290625
and memtable_throughput = 62
and memtable_flush_after = 1440
and rows_cached = 0.0
and row_cache_save_period = 0
and keys_cached = 200000.0
and key_cache_save_period = 14400
and read_repair_chance = 1.0
and gc_grace = 864000
and min_compaction_threshold = 4
and max_compaction_threshold = 32
and replicate_on_write = true
and row_cache_provider = 'ConcurrentLinkedHashCacheProvider'
and column_metadata=[
{column_name: allias, validation_class: UTF8Type, index_type: KEYS, index_name: allias},
{column_name: st_user_id, validation_class: TimeUUIDType, index_type: KEYS, index_name: st_user_id},
{column_name: st_money, validation_class: IntegerType},
{column_name: mail, validation_class: UTF8Type},
{column_name: password, validation_class: UTF8Type},
{column_name: last_visit, validation_class: DateType},
{column_name: registered, validation_class: DateType}
];
But im getting an exception:
org.apache.cassandra.db.marshal.MarshalException: unable to coerce
'allias' to v ersion 1 UUID
What i am doing wrong?
The comparator property of a column family is used for ordering the columns within a row. You are attempting to use a TimeUUID comparator, which would require that each column name be a TimeUUID value.
If you want to use TimeUUIDs as your row keys, but strings for column names you likely just want to switch the values for those settings,
comparator = 'UTF8Type',
key_validation_class = 'TimeUUIDType'
Related
after reading all the "INSERT INTO" posts as well as the documentation, I am still unsure whether what I want is feasible or not.
I want to change the UPDATE below into an INSERT INTO, because I have many 100-thousands of them (speed issues):
UPDATE city c
SET
c.g17h = '3196504',
c.g17q = '2593487',
c.g17k = '0',
c.g17w = '0',
c.g17s = '0'
WHERE
p17t = 30 AND p17l = '30';
or
UPDATE city c
SET
c.g1h = '0',
c.g1q = '0',
c.g1k = '0',
c.g1w = '0',
c.g1s = '0'
WHERE
p1t = 1
AND p1l = '1';
However, my best solutions do not work:
INSERT INTO city (g17h, g17q, g17k, g17w, g17s)
SELECT
'3196504',
'2593487',
'0',
'0',
'0'
FROM valuestoretab
WHERE
p17t = 30
AND p17l = '30';
This is of course because my WHERE condition can only be satisfied in the first table (city) but not in the second one which is just a table of values, whereas the city table is a data set where each id has particular values for p17t, p17l and so on.
For clarification:
The first table (city) looks like
cityid1, ownerid1, islandid1, p17t, p17l
cityid2, ownerid2, islandid2, p17t, p17l
with different values for each row for p17t and p17l.
So, my questions would be:
1. Is it at all possible to write a INSERT-Query with a WHERE condition for the table that is being inserted into?
2. If no, do I have to stick to my UPDATE or is there another (fast!) solution?
Thanks to the community!
litotes
To give a quick answer insert with a select statement is possible
Insert INTO MyTable (Val1, Val2)
Select
SomeValue,
AnotherValue
From MyOtherTable
Where Date = Getdate()
On the other hand, you can also update many records like in the following example:
Update t1
Set
t1.Val1 = t2.SomeValue,
t1.Val2 = t2.AnotherValue
From MyTable t1
Inner join MyOtherTable t2 ON t1.PK = t2.FK
where t2.Date = getdate()
EDIT:
When i read the following query, I presume p17t and p17l are from the valuestoretab.
UPDATE city c
SET
c.g17h = '3196504',
c.g17q = '2593487',
c.g17k = '0',
c.g17w = '0',
c.g17s = '0'
WHERE
p17t = 30 AND p17l = '30';
==> changed this into:
UPDATE c
SET
c.g17h = '3196504',
c.g17q = '2593487',
c.g17k = '0',
c.g17w = '0',
c.g17s = '0'
FROM City c, ValueStoreTab v
WHERE
c.SomeCol = v.SomeCol -- Here, your relation must exist!
AND v.p17t = 30 AND v.p17l = '30';
I'm trying to migrate some data from an old database to a new one with a slightly different schema and my SQL isn't terribly strong.
Old schema: There is a table we'll call "Person" with a field which can have set of permutations of 3 flags. The Person table has a foreign key to another table we'll call "Flags". They Flags table has rows for each of these flag combinations in a String:
1 - Yes No No
2 - Yes Yes No
3 - Yes No Yes
4 - Yes Yes Yes
5 - No Yes No
6 - No Yes Yes
7 - No No Yes
The new schema doesn't require this table (thankfully). These flags are simply fields in the "Person" table now as BIT fields.
What I want to do is something like a:
UPDATE database2.Person SET (flag1, flag2, flag3) VALUES (true, false false) WHERE database1.Person.flag_id = 1;
I could then run 7 different queries changing the IDs and the values accordingly. The problem, of course, is that the above isn't correct SQL. I think I need some kind of JOIN ...or a subselect in the where clause or something?
Stumped on the best way forward. My parting thought here is that this doesn't need to be compressed into a single query, or particularly elegant. I expect to run this query once and be done with it.
You could try something like:
update database2.Person p2 join database1.Person p1 on p1.PersonId = p2.PersonId
set flag1 = case when p1.Flag_id in (1,2,3,4) then true else false end case,
flag2 = case when p1.Flag_id in (2,4,5,6) then true else false end case,
flag3 = case when p1.Flag_id in (3,4,6,7) then true else false end case
(edited for mySQl syntax)
This should work if I'm understanding your question. It assumes you have a Person_Id matching in each table.
UPDATE db2.Person p
JOIN db1.Person p2 ON p.Person_Id = p2.Person_Id
SET p.Flag1 = 1,
p.Flag2 = 0,
p.Flag3 = 0
WHERE p2.Flag_Id = 1;
If the flag values in the Flags table were columns, you could easily run a single query, but as I'm understanding it, it's just a string field. This is an example:
UPDATE db2.Person p
JOIN db1.Person p2 ON p.Person_Id = p2.Person_Id
JOIN db1.Flags f ON p2.Flag_Id = f.Flag_Id
SET p.Flag1 = CASE WHEN f.Flag1 = 'Yes' THEN 1 ELSE 0 END,
p.Flag2 = CASE WHEN f.Flag2 = 'Yes' THEN 1 ELSE 0 END,
p.Flag3 = CASE WHEN f.Flag3 = 'Yes' THEN 1 ELSE 0 END
No matter what I do in MySQL 5.0 such as
SELECT 'test' = FALSE
SELECT '' = FALSE
I always get a 1 back in SQL. What is the reason for that? I was expecting a 0 or FALSE
EDIT adding context to the questions.
This is how the problem came about, it happened that $name inadvertently became false making this join always pass, then I wondered why this works.
SELECT a.id
FROM user a
INNER JOIN inventory b ON b.user_id = a.id AND b.name = $name
In MySql FALSE is a constant literal which is always evaluated as 0.
So you are checking if 'test' = 0 or if '' = 0, and since you are comparing a string with an integer, MySql will try to cast the string to an integer.
If you try this query:
SELECT 'test' = FALSE
it will return 1 (TRUE) because 'test' will be converted to 0, while if you try this:
SELECT '1test' = FALSE
it will return 0 (FALSE) because '1test' will be converted to 1.
This has to do with MySQL's implicit conversion when using comparison operators (i.e. =)
Taken from the docs:
Strings are automatically converted to numbers and numbers to strings as necessary.
So, in your case:
'test' gets converted to 0
FALSE is 0
0 = 0 is TRUE.
I need to check if the column exam has a value of true. So I set this up but it doesn't work...
#exam_shipments = Shipment.where("exam <> NULL AND exam <> 0 AND customer_id = ?", current_admin_user.customer_id)
# This one gives me error "SQLite3::SQLException: no such column: true:"
#exam_shipments = Shipment.where("exam = true AND customer_id = ?", current_admin_user.customer_id)
#exam_shipments = Shipment.where("exam = 1 AND customer_id = ?", current_admin_user.customer_id)
You should really just stick to AR syntax:
#exam_shipments = Shipment.where(:exam => true, :customer_id => current_admin_user.customer_id)
Assuming :exam is a boolean field on your Shipment model. ActiveRecord takes care of converting your query to the proper syntax for the given database. So the less inline SQL you write, the more database-agnostic and portable your code will be.
Why do you need do execute SQL?
It's much easier just to do
#exam_shipments = Shipment.find_by_id(current_admin_user.customer_id).exam?
This is the code I am using
# update db
client = Mysql2::Client.new(:host => "localhost", :username => "jo151", :password => "password", :database => "jo151")
details.each do |d|
if d[:sku] != ""
price = d[:price].split
if price[1] == "D"
currency = 144
else
currency = 168
end
cost = price[0].gsub(",", "").to_f
if d[:qty] == ""
qty = d[:qty2]
else
qty = d[:qty]
end
results = client.query("SELECT * FROM jos_virtuemart_products WHERE product_sku = '#{d[:sku]}' LIMIT 1;")
if results.count == 1
product = results.first
client.query("UPDATE jos_virtuemart_products SET product_sku = '#{d[:sku]}', product_name = '#{d[:desc]}', product_desc = '#{d[:desc]}', product_in_stock = '#{qty}' WHERE virtuemart_product_id =
#{product['virtuemart_product_id']};")
client.query("UPDATE jos_virtuemart_product_prices SET product_price = '#{cost}', product_currency = '#{currency}' WHERE virtuemart_product_id = '#{product['virtuemart_product_id']}';")
else
client.query("INSERT INTO jos_virtuemart_products( product_sku, product_name, product_s_desc, product_in_stock) VALUES('#{d[:sku]}','#{d[:desc]}','#{d[:desc]}','#{d[:qty]}');")
last_id = client.last_id
client.query("INSERT INTO jos_virtuemart_product_prices(virtuemart_product_id, product_price, product_currency) VALUES('#{last_id}', '#{cost}', #{currency});")
end
end
end
`query': Duplicate entry '' for key 3 (Mysql2::Error) on line 35:
client.query("INSERT INTO jos_virtuemart_products( product_sku, product_name, product_s_desc, product_in_stock) VALUES('#{d[:sku]}','#{d[:desc]}','#{d[:desc]}','#{d[:qty]}');")
last_id = client.last_id
Putting in raw SQL statements with arbitrary strings inlined like this is extremely dangerous. You absolutely must escape any values put into them for your application to work at all. The first description you get with an apostrophe will cause your SQL to fail.
In this case you would use client.quote on each and every one of the strings. No exceptions. You have probably seen tons of press about Sony getting hacked, and it's because of mistakes like this that serious breaches happen.
You should investigate using an ORM to help with this, even something as simple as Sequel or DataMapper, as they provide facilities to make this easy.
The reason you are getting a duplicate key is because you have a unique index on one of the columns you're inserting into, or one of the columns is not specified and has a default value that collides with an existing row.