How do I dynamically change constant assignment? - ruby

I'm writing an insert with a select:
my_object_id = 7
id_list = [1,2,4,5]
TEST_TEMPLATE = %Q{
INSERT INTO tests
(test_id, data_id, text, created_at, updated_at)
select #{my_object_id}, data_id, text, created_at, updated_at
from tests where id in (#{id_list})
}
ActiveRecord::Base.connection.execute(TEST_TEMPLATE);
I get error that I cannot change the constant. How do I inject values into a string so I can use it in my insert/select statements?
How can this be solved in Ruby?

Here's a bit of an explanation to #SergioTulentsev answer:
You should change the first letter of TEST_TEMPLATE to lowercase, because variables starting with uppercase letters are not actually variables, they are constants, so you shouldn't change them.
As #SergioTulentsev shows in his code, you should change every letter to lowercase to match the style-conventions used in Ruby.

There's no reason to make it a constant.
my_object_id = 7
id_list = [1,2,4,5]
test_template = %Q{
INSERT INTO tests
(test_id, data_id, text, created_at, updated_at)
select #{my_object_id}, data_id, text, created_at, updated_at
from tests where id in (#{id_list})
}
ActiveRecord::Base.connection.execute(test_template)

Related

ORA-00936: missing expression using SELECT INTO local_variable

I am trying to assing a result to a local variable in stored procedure sql.
For example
Select c.parm_val from Cusomter.name c where c.id = '102';
The above query gives me a result like 36,1508,4399,4403,4405,4407,4409,4411,4419
I want to assign it to a local variable
So I created in stored procedure like below
DECLARE
values VARCHAR2(500 BYTE);
BEGIN
Select into values c.parm_val from Cusomter.name c where c.id = '102';
END
When I execute this I get different errors each time
Something like PL/SQL: ORA-00936: missing expression
I want to assign those result a variable. I don't know if I can use INSERT as it not a table.
Can someone help me how to assign it to a variable.
I'm not sure about the syntax you are using. The FROM clause requires a table name like Customer, not Customer.name, which seems to be a column.
Starting with 11g Release 2 you can use the LISTAGG function to concatenate a column from the result rows into a single string.
SELECT LISTAGG(c.name, ',') WITHIN GROUP (ORDER BY c.name) INTO "values"
FROM Customer c
WHERE c.id = '102';
If c.id has a numeric type, drop the quotes: WHERE c.id = 102.
According to your comment, you probably want something like
SELECT c.name INTO "values"
FROM Customer c
WHERE c.id = '102';
See: PL/SQL SELECT INTO
Also, VALUES is a reserved word in SQL. Therefore, either choose another name, or escape it as "values" (in the declaration as well).
INTO comes after the field list:
Select c.parm_val into values from Cusomter.name c where c.id = '102';

Compare two records and highlight the differences

I have a oracle apex report which fetches two rows every time.
I want to highlight all the columns where data is different in two rows.
So when user looks at the comparison report he don't have to go through all the columns to identify where data has been changed.
I have tried to look at the apex features and some javascript code but was unable to do so reliably.
You can have a look at sample report here:
https://apex.oracle.com/pls/apex/f?p=128616:8:109311280077805:::::
go to page "help me with comparison"
I want to highlight the benefit name column as data is different in benefit name column.
if your table has id "test" you can try call this function on page load compareRows(document.getElementById('test'));
the function body:
function compareRows(table) {
var row1,row2, rows = table.rows;
var cell1,cell2;
var rowText;
row1=rows[1];
row2=rows[2];
cell1=row1.cells;
cell2=row2.cells;
for (var i=0; i<cell1.length; i++) {
if(cell1[i].textContent != cell2[i].textContent){
cell1[i].style.backgroundColor = "red";
cell2[i].style.backgroundColor = "red";
}
}
}
You can use the analytic function "LAG" to reference the previous row in your resultset.
So one possible solution is to (1) select the value of the current row and the value of the previous row, (2) compare the 2 columns and set a flag, only in row 2 because that is where you want to highlight, (3) use highlighting in apex to indicate which columns have different values. See example sql below for an example.
-- create tables
create table so_dummy_data (
id number generated by default on null as identity
constraint so_dummy_data_id_pk primary key,
name varchar2(100) not null,
email varchar2(100) not null
)
;
-- load data
insert into so_dummy_data (
id,
name,
email
) values (
1,
'John Doe',
'john.doe#mail.com'
);
insert into so_dummy_data (
id,
name,
email
) values (
2,
'John Doe',
'john.x.doe#mail.com'
);
commit;
WITH old_and_new AS
(SELECT
id,
name,
LAG(name,1)OVER(
ORDER BY
name
)AS new_name,
email,
LAG(email,1)OVER(
ORDER BY
1
)AS new_email,
row_number() over (order by 1) rn
FROM
so_dummy_data
)
SELECT
name,
CASE
WHEN rn = 1 THEN 'N'
WHEN name = new_name THEN
'N'
ELSE
'Y'
END AS name_changed,
email,
CASE
WHEN rn = 1 THEN 'N'
WHEN email = new_email THEN
'N'
ELSE
'Y'
END AS email_changed
FROM
old_and_new;

Reverse SQL like not working in Oracle 12c

I need to do a reverse like query in Oracle 12c. While it works fine with H2, it fails in Oracle12c.
Table:
CREATE TABLE t
("id" int, "code" varchar(100))
;
INSERT ALL
INTO t ("id", "code")
VALUES (1, 'london')
INTO t ("id", "code")
VALUES (2, 'amsterdam')
INTO t ("id", "code")
VALUES (3, 'Oslo')
INTO t ("id", "code")
VALUES (4, 'Brussels')
SELECT * FROM dual
;
Query:
select * from t where 'london south' like concat('%',code, '%');
It gives error: ORA-00909: invalid number of arguments
How should i query it get (1, london) as the result?
Do NOT use double quotes around lower case column names in your DDL unless you really want to force Oracle to store the column names in lower case, which also means you need to use double quotes in your query:
select * from t where 'london south' like '%'||"code"||'%' ;
got the value london as the single row of output.
Why use the concat function when using || is more flexible?
Here you are a simpler test case:
select concat('a', 'b', 'c')
from dual;
ORA-00909: invalid number of arguments
The CONCAT() function expects exactly two arguments. You'll have to nest several calls or use the || operator.
select *
from t
where 'london south' like '%' || code || '%';

Oracle select string to boolean in select statement

I am new to Oracle :)
I have this statement has a string value called Active. The value can be Y or N. I want to do a select statement that returns a boolean value for that field.
Currently it looks like this:
select h.catalogueid ID,
h.cataloguename NAME,
h.uniquecatalogue INCLUDEPRODUCTS,
h.active ACTIVE,
h.ownbrandedlabels OWNLABELS
from cc_ob_catalogueheader h
I would like to do something like this:
select h.catalogueid ID,
h.cataloguename NAME,
h.uniquecatalogue INCLUDEPRODUCTS,
h.active = 'Y' ACTIVE,
h.ownbrandedlabels OWNLABELS
from cc_ob_catalogueheader h
But that is syntaxly incorrect. Does anyone know how I can do this?
I solved this myself.
I changed my select statement to this:
select h.catalogueid ID,
h.cataloguename NAME,
h.uniquecatalogue INCLUDEPRODUCTS,
CASE WHEN (h.active = 'Y') THEN 1 ELSE 0 END ACTIVE,
h.ownbrandedlabels OWNLABELS
from cc_ob_catalogueheader h

Oracle unions in the wrong order

I'm trying to understand why my query is returning things in a different order than I expect.
My query is:
SELECT 'PRINTJOBID', MAX(PRINTJOBID), null, null FROM PRINTJOB
UNION
SELECT 'AUTOID', null, MAX(AUTOID), null FROM PRINTJOBSHELLS
UNION
SELECT 'PROCESSLOGID', null, null, MAX(PROCESSLOGID) FROM PROCESSLOG;
I am expecting it to give me 3 rows, with printjobid at the top, followed by autoid, and then at the bottom should be processlogid. However, when I run the query I get autoid at the top, printjobid in the middle, and processlog at the bottom, like this:
AUTOID null 771426 null
PRINTJOBID 76401 null, null
PROCESSLOGID null null 1218693
I have tried googling about Unions being in the wrong order, and I tried searching questions on SO. I didn't see anything that seemed relevant. Is my understanding of how UNION works faulty? I thought that the query would return the rows in the order I put the select statements. Thank you!
In SQL, you can't rely on a query returning results in any special order unless you explicitly specify it in the query.
Use this:
SELECT title, v1, v2, v3
FROM (
SELECT 'PRINTJOBID' title, MAX(PRINTJOBID) v1, null v2, null v3, 1 AS o
FROM PRINTJOB
UNION ALL
SELECT 'AUTOID' title, null, MAX(AUTOID), null, 2 AS o
FROM PRINTJOBSHELLS
UNION ALL
SELECT 'PROCESSLOGID' title, null, null, MAX(PROCESSLOGID), 3 AS o
FROM PROCESSLOG
)
ORDER BY
o
If you want ordering of results, you need to specify an ORDER BY clause. Otherwise you are relying on implementation-specific behaviour. In this case it is probably lucky you did not get the ordering you hoped for originally, as the behaviour could easily change in future, so you need to explicitly specify ordering if it is important to you.

Resources