How do I create a prepared insert statement in Sequel? - ruby

I am attempting to create a prepared insert statement in Sequel and I am as far as
db[:registration].prepare(:insert)
=> <Sequel::Mysql2::Dataset/PreparedStatement "INSERT INTO `registration` () VALUES ()">
How do I create a statement that is something like the following:
INSERT INTO `registration` (`name`, `email`) VALUES (?, ?)
The documentation is a little bit obtuse and I can't find any examples online.

Figured this out looking at their rspecs:
statement = db[:registration].prepare(:insert, :prepared_statement_name, :email => :$email, :name => :$name)
statement.call(:name => "foo", :email => "foo#bar.com")
NOTE
The keys that are passed to .call correspond to the values passed in the hash in prepare. So this would work too:
statement = db[:registration].prepare(:insert, :prepared_statement_name, :email => :$e, :name => :$n)
statement.call(:n => "foo", :e => "foo#bar.com")

ds = db[
"INSERT INTO `registration` (`name`, `email`) VALUES (?, ?)",
name, email
]
ds.call(:insert)

Related

how convert sql to Laravel

I am new to laravel, I am having trouble converting my sql to Laravel Query.
Example
INSERT INTO table(field1, field2) SELECT 'value1', 'value2' WHERE NOT EXISTS(SELECT 1 FROM tabla WHERE campo = 'search');
this is my code
INSERT INTO siryus.presupuesto_anio (id, fk_agencia_id, anyo, estado, created_at, updated_at) SELECT 30,4,2020, 'A', '2021-04-21 10:35:01','2021-04-21 10:35:01' WHERE NOT EXISTS(SELECT 1 FROM presupuesto_anio WHERE fk_agencia_id = '4');
i want insert only if there is no field with that value. The insert is done only if there are values ​​of the select, and the select will return data only if the WHERE is met.
Inside the WHERE we have a simple SELECT that verifies if the data exists in the table.
I want to convert it to example code
DB::table('presupuesto_anio') ->join('agencia','presupuesto_anio.fk_agencia_id','agencia.id') ->select('presupuesto_anio.*','agencia.descripcion') ->get();
im not understand with your questions, maybe this will help:
$check = Model::where('id', 4)->first();
if(!$check){
Model::create({
'column1' => 'value1',
'column2' => 'value2'
});
}

Batch insert in Laravel 5.2

I am using a API's with lot's of calculation almost 100 database fields at the end with a big Foreach loop.
In every iteration i insert data in database. I want to insert data in once at the end (Batch Insert like in CodeIgniter).
Any body have idea how to insert all data at the end of iteration. instead of every iteration it insert row in database.
I want to insert data at the end of loop. Any help or idea appreciated.
Use insert() method for bulk insertion. First, build an array with this structure:
$data = [
['name' => 'John', 'age' => 25],
['name' => 'Maria', 'age' => 31],
['name' => 'Julia', 'age' => 55],
];
Then insert the data using Eloquent model:
Model::insert($data);
Or using query builder:
DB::table('table_name')->insert($data);

DBMS_STATS with Looping

I just tried to learn new things. I just make a experiment to analyze tables with looping. But, I found error that said
'Invalid reference to variable 'indx'
. If I take out the DBMS_STATS 'thing' and just to print the result, it works. But when I tried to analyze the tables, the error came out.
CREATE OR REPLACE PROCEDURE ANALYZE_TABLE
AS
CURSOR table_cur IS
SELECT TABLE_NAME
FROM ALL_TABLES
WHERE TABLE_NAME LIKE 'STUDENT%';
table_nm table_cur%ROWTYPE;
TYPE table_nms IS TABLE OF table_nm%TYPE;
l_table table_nms;
BEGIN
OPEN table_cur;
FETCH table_cur BULK COLLECT INTO l_table;
CLOSE table_cur;
FOR indx IN 1..l_table.COUNT LOOP
IF (indx.table_name = 'STUDENT_DETAILS') THEN
dbms_stats.gather_table_stats(ownname => 'ADMIN', tabname => indx.table_name , estimate_percent => 100,
method_opt => 'for all indexed columns size auto',
degree => 4 ,cascade => TRUE );
ELSIF (indx.table_name = 'STUDENT_ALLOWANCE' OR indx.table_name = 'STUDENT_PAYMENT')
THEN
DBMS_STATS.GATHER_TABLE_STATS (ownname => 'ADMIN', tabname => indx.table_name , estimate_percent => 100,
method_opt => 'for all indexed columns size auto',
degree => 4 ,cascade => TRUE );
ELSE
DBMS_STATS.GATHER_TABLE_STATS (ownname => 'ADMIN', tabname => indx.table_name , estimate_percent => 100,
method_opt => 'for all indexed columns size auto',
degree => 4 ,cascade => TRUE );
END IF;
--DBMS_OUTPUT.PUT_LINE(l_table(indx).TABLE_NAME);
END LOOP;
END ANALYZE_TABLE;
Any suggestion? Or a better way to analyze tables with this loop?
Thank you in advance for anyone that helping me. :)
You need to reference the contents of your array, not the loop index. The loop index tells you which element in the array. So:
IF (l_table(indx).table_name = 'STUDENT_DETAILS') THEN
and so on
You should reference the values in your table as follows:
if (l_table(indx).table_name = 'STUDENT_DETAILS') ...

Rails 4: column reference "updated_at" is ambiguous with Postgres

I am trying to query the database with a DateTime range for the 'updated_at' field. The front end sends queries in a JSON array:
["2015-09-01 00:00:00","2015-10-02 23:00:00"]
At the Rails controller, I parse the two strings to DateTime using:
start_date = DateTime.parse(params[:date_range_arr][0])
end_date = DateTime.parse(params[:date_range_arr][1])
#...
#events = #events.where('updated_at BETWEEN ? AND ?,
start_date, end_date
)
The queries show:
WHERE (updated_at BETWEEN '2015-09-01 00:00:00.000000' AND '2015-10-02 23:00:00.000000')
And the errors are:
ActionView::Template::Error (PG::AmbiguousColumn: ERROR: column reference "updated_at" is ambiguous
LINE 1: ...texts"."id" = "events"."context_id" WHERE (updated_at...
Do you have by any chance a default scope with a join or an include on the Event model or in the code above what's included in the original question?
Either way, you simply need to be more specific with your query as follow:
#...
#events = #events.where('events.updated_at BETWEEN ? AND ?,
start_date, end_date
)

Multiple aggregate queries using the sequel gem

Is it possible to use sequel to execute a query like this:
select (select count(*) from users where blah = 'blah') as "users",
(select count(*) from contacts where blah = 'blah') as "contacts"
I know I can execute these queries one a time using sequel, but I would like to execute them all at the same time.
You can do that query without writing raw SQL with the following:
dataset = DB.select {[
DB[:users].where(blah: 'blah').select { count('*') }.as(:users),
DB[:contacts].where(blah: 'blah').select { count('*') }.as(:contacts)
]}
dataset.first
# => { users: X, contacts: Y }
dataset.sql
# => "SELECT (SELECT count('*') FROM \"users\" WHERE (\"blah\" = 'blah')) AS \"users\",
# (SELECT count('*') FROM \"contacts\" WHERE (\"blah\" = 'blah')) AS \"contacts\""
Yes you can do it ok with the sequel gem.
require 'sequel'
DB = Sequel.sqlite # memory database
DB.create_table :users do
primary_key :id
String :name
end
users = DB[:users] # Create a dataset
users.insert(:name => 'jim')
DB.create_table :contacts do
primary_key :id
String :name
end
contacts = DB[:contacts] # Create a dataset
contacts.insert(:name => 'first')
DB['select (select count(*) from users where name = "jim") as users,
(select count(*) from contacts where name = "first") as contacts'].each do |row|
puts row
end
#{:users=>1, :contacts=>1}
It should be noted however that it is not a great idea to include raw strings in a sequel method.
They can be extracted as follows:
DB['select (select count(*) from users where name = ?) as users,
(select count(*) from contacts where name = ?) as contacts, 'jim', 'first'].each do |row|
puts row
end
Also as noted in another answer you could express this query completely without resorting to SQL which is more in the spirit of the module. :
dataset = DB.select {[
DB[:users].where(name: 'jim').select { count('*') }.as(:users),
DB[:contacts].where(name: 'first').select { count('*') }.as(:contacts)
]}
dataset.sql
# SELECT (SELECT count('*') FROM `users` WHERE (`name` = 'jim')) AS 'users', (SELECT count('*') FROM `contacts` WHERE (`name` = 'first')) AS 'contacts'
dataset.first
# {:users=>1, :contacts=>1}
You can execute as you mentioned above, there is no issue with your query .
I have executed the same and it was executed without any issues ..
below was what i have executed
select( SELECT count(*) FROM `abcde` where `User_ID`=4001) as "aa",
(SELECT count(*) FROM `abcdef` where `User_ID`=4018) as "bbb"
results :
aa bbb
181 364
you need to add * from after select and may be some parenthesis:
select * from ((select count(*) from users where blah = 'blah') as "users",
(select count(*) from contacts where blah = 'blah') as "contacts")

Resources