I have the following select statement that works just fine:
select stock_master.stock_code, stk_stock_status, reorder_buyer, default_route_id, main_work_centre
from stock_master, bill_of_materials_header, production_routing
where stock_master.stock_code = bill_of_materials_header.stock_code
and bill_of_materials_header.default_route_id = production_routing.prh_route_id
and main_work_centre != "CNC";
and stock_group >= 3201 and stock_group <= 3299;
What I want to do is update the stk_stock_status to "M" for this condition, but can't seem to work out the correct syntax for the update command. Any pointers would be extremely helpful.
If stk_stock_status is instock_master table and this table has some ID column then convert your select into select that returns only identifiers which should be updated. It will look like:
UPDATE stock_master SET stk_stock_status = 'M' WHERE stk_stock_id IN
(
SELECT stk_stock_id
FROM stock_master, bill_of_materials_header, production_routing
WHERE stock_master.stock_code = bill_of_materials_header.stock_code
AND bill_of_materials_header.default_route_id = production_routing.prh_route_id
AND main_work_centre != 'CNC';
)
PS Do not use " for sting literals. It is allowed by Informix but not by SQL standard. Better use '.
Related
Would you please provide an an example for a Redshift procedure where you have used a cursor and an UPDATE statement in conjunction? Is that even feasible, I couldn't find an example. I'm looking for a simple template code to learn how to have these 2 together in a single procedure on Redshift.
Here is an example use case:
I have a table like this:
CREATE TABLE test_tbl
(
Contactid VARCHAR(500),
sfdc_OppId_01 VARCHAR(500),
sfdc_OppId_02 VARCHAR(500),
sfdc_OppId_03 VARCHAR(500),
sfdc_OppId_04 VARCHAR(500),
sfdc_OppId_05 VARCHAR(500),
sfdc_OppId_06 VARCHAR(500)
)
I want to update each sfdc_OppId_xx with the relative value from another table; sfdc_tbl. Here is what sfdc_tbl looks like:
sfdc_contactId
sfdc_Opp_Id
AA123hgt
999999
AA123hgt
888888
AA123hgt
777777
AA123hgt
432567
AA123hgt
098765
AA123hgt
112789
So as you see, there are duplicate sfdc_contactid in the sfdc_tbl. My final goal is to list all the sfdc_Opp_Id for given contactid horizontally in the test_tbl. I shall not have duplicate contactid in the test_tbl.
INSERT INTO test_tbl (Contactid)
SELECT sfdc_contactId
FROM sfdc_tbl
GROUP BY sfdc_contactId
And here is what I'm trying to do:
CREATE OR REPLACE PROCEDURE testing_procedure (results INOUT refcursor)
AS
$$
BEGIN
OPEN cursor_testing FOR
SELECT
Ops.sfdc_Opp.id,
ROW_NUMBER () OVER(PARTITION BY Ops.sfdc_contactId ORDER BY sfdc_Opp_Id ) RWN
FROM sfdc_tbl Ops
INNER JOIN test_tbl tbl
ON Ops.sfdc_contactId = tbl.contactid;
UPDATE test_tbl
SET sfdc_Opp_01 = CASE WHEN cursor_testing.RWN = 1 THEN cursor_testing.sfdc_Ops_id ELSE NULL END,
sfdc_Opp_02 = CASE WHEN cursor_testing.RWN = 2 THEN cursor_testing.sfdc_Ops_id ELSE NULL END,
sfdc_Opp_03 = CASE WHEN cursor_testing.RWN = 3 THEN cursor_testing.sfdc_Ops_id ELSE NULL END,
sfdc_Opp_04 = CASE WHEN cursor_testing.RWN = 4 THEN cursor_testing.sfdc_Ops_id ELSE NULL END,
sfdc_Opp_05 = CASE WHEN cursor_testing.RWN = 5 THEN cursor_testing.sfdc_Ops_id ELSE NULL END,
sfdc_Opp_06 = CASE WHEN cursor_testing.RWN = 6 THEN cursor_testing.sfdc_Ops_id ELSE NULL END
;
END;
$$
LANGUAGE plpgsql;
I keep getting an error
incorrect syntax at or near "cursor_testing"
I've answered a question with a similar solution. The SQL uses a cursor's data to INSERT into a table and this same path should work for UPDATE - How to join System tables or Information Schema tables with User defined tables in Redshift
That being said and looking at your code I really think you would be better off using a temp table rather than a cursor. The first thing to note is that a cursor is not a table. Your use pattern won't work AFAIK. You read a cursor row by row (or bunches) which is contrary to Redshift's columnar table storage. So you will need to loop on the rows from the cursor and perform N updates. This will be extremely slow! You would be querying columnar data, storing the results in a cursor as rows, reading these row one by one, and then performing a new query (UPDATE) for each row. Ick! Stay in "columnar land" and use a temp table.
I'm trying to parameterize my postgresql query in order to prevent SQL injection in my ruby on rails application. The SQL query will sum a different value in my table depending on the input.
Here is a simplified version of my function:
def self.calculate_value(value)
calculated_value = ""
if value == "quantity"
calculated_value = "COALESCE(sum(amount), 0)"
elsif value == "retail"
calculated_value = "COALESCE(sum(amount * price), 0)"
elsif value == "wholesale"
calculated_value = "COALESCE(sum(amount * cost), 0)"
end
query = <<-SQL
select CAST(? AS DOUBLE PRECISION) as ? from table1
SQL
return Table1.find_by_sql([query, calculated_value, value])
end
If I call calculate_value("retail"), it will execute the query like this:
select location, CAST('COALESCE(sum(amount * price), 0)' AS DOUBLE PRECISION) as 'retail' from table1 group by location
This results in an error. I want it to execute without the quotes like this:
select location, CAST(COALESCE(sum(amount * price), 0) AS DOUBLE PRECISION) as retail from table1 group by location
I understand that the addition of quotations is what prevents the sql injection but how would I prevent it in this case? What is the best way to handle this scenario?
EDIT: I added an extra column to be fetched from the table to highlight that I can't use pick to get one value.
find_by_sql is used when you want to populate objects with a single line of literal SQL. But we can use ActiveRecord for most of this, we just need one single column. To make objects, use select. If you just want results use pluck.
As you're picking from a fixed set of strings there's no risk of SQL injection in this code. Use Arel.sql to pass along a SQL literal you know is safe.
def self.calculate_value(result_name)
sum_sql = case result_name
when "quantity"
"sum(amount)"
when "retail"
"sum(amount * price)"
when "wholesale"
"sum(amount * cost)"
end
sum_sql = Arel.sql(
"coalesce(cast(#{sum_sql} as double precision), 0) as #{result_name}"
)
return Table1
.group(:location)
# replace pluck with select to get Table1 objects
.pluck(:location, sum_sql)
end
i am using informix DB , i need to get records that contain alpha [A-Za-z] character on last character
what i try is :
select * from table_name
where (SUBSTR(trim(customer),-1,1)!='0' and SUBSTR(trim(customer),-1,1)!='1' and SUBSTR(trim(customer),-1,1)!='2' and SUBSTR(trim(customer),-1,1)!='3' and SUBSTR(trim(customer),-1,1)!='4' and SUBSTR(trim(customer),-1,1)!='5' and SUBSTR(trim(customer),-1,1)!='6' and SUBSTR(trim(customer),-1,1)!='7' and SUBSTR(trim(customer),-1,1)!='8' and SUBSTR(trim(customer),-1,1)!='9') or (SUBSTR(trim(customer),-1,1)=' ') or (SUBSTR(trim(customer),-1,1)='') or (customer IS NULL)
is there are any way to write where SUBSTR(trim(customer),-1,1)=alpha rather than write
SUBSTR(trim(customer),-1,1)!='0' and SUBSTR(trim(customer),-1,1)!='1' and SUBSTR(trim(customer),-1,1)!='2' and SUBSTR(trim(customer),-1,1)!='3' and SUBSTR(trim(customer),-1,1)!='4' and SUBSTR(trim(customer),-1,1)!='5' and SUBSTR(trim(customer),-1,1)!='6' and SUBSTR(trim(customer),-1,1)!='7' and SUBSTR(trim(customer),-1,1)!='8' and SUBSTR(trim(customer),-1,1)!='9'
If you have a 'recent' version of Informix (anything over 12.10 should do) you can use regex_match():
https://www.ibm.com/support/knowledgecenter/SSGU8G_14.1.0/com.ibm.dbext.doc/ids_dbxt_544.htm
Something like :
> select * from table(set{'test','test1','tesT'})
where regex_match(unnamed_col_1, '[a-zA-Z]$');
unnamed_col_1
test
tesT
2 row(s) retrieved.
>
You can use the Informix MATCHES operator, that is supported in any version.
The query would be like this:
select * from table_name
where customer matches "*[A-Za-z]"
I am using sqlite in one my ios project where among other columns there are two columns. one has country code for mobile dialing like +880 and other column has rest of the mobile number like 1912353697. Now i want to join values from these two columns and compare the result value against like +8801912353697 and if matches pull the corresponding name value in that table . what would be the right query. I have tried like SELECT name FROM CONTACT_LIST WHERE (SELECT mblDc || mbl FROM CONTACT_LIST) = "+8801617634317" ; but that does not work .
A help would be appreciated.
Try:
SELECT name FROM CONTACT_LIST
WHERE mblDc || mbl = "+8801617634317";
From SQLite documentation: The || operator is "concatenate" - it joins together the two strings of its operands.
please check
How to concatenate strings with padding in sqlite
using substr function we can do the job and the query should be like
SELECT name FROM CONTACT_LIST WHERE (mblDc || mbl) = "+8801617634317" ;
So I have an update statement:
UPDATE billing_infos set card_number = ''
FROM orders
WHERE billing_infos.order_id = orders.id ...);`
How would I find the count of how many records are updated by this statement?
I'm doing this in my console through ActiveRecord::Base.connection.execute() so it's just returning a <PG::Result:0x007f9c99ef0370> object.
Anyone know how I could do this using SQL or a Rails method?
p = ActiveRecord::Base.connection.execute(<query>)
p.cmd_status
This gives the command status. Something like
UPDATE 16
For more methods on PG::Result, refer here
While solution showed by Vimsha will definitely work, there is also another solution (assuming you use recent enough pg), which could be a bit nicer:
with u as (
update ... returning 1
)
select count(*) from u;
That's one query, and it's technically a select, so you run it as any other select.
As mentioned in a comment of another answer, the easiest way is to use the cmd_tuples attribute of the result
result = ActiveRecord::Base.connection.execute("insert into tbl select 'test' col")
puts result.cmd_tuples
result
1