is the supabase api able to delete multiple rows at a time which are each identified by multiple column values?
something like:
const { data, error } = await supabase
.from('list_members')
.delete()
.in('{list_id,contact_id}', ['{7,2}', '{7,4}']);
?
as opposed to a bulk delete using a single column which is supported:
const { data, error } = await supabase
.from('cities')
.delete()
.in('id', ['1', '2'])
(aka this question but for supabase)
UPDATE
if anyone's curious this is the postgres function i wrote instead, based on much SO guidance. no guarantee on efficiency but it works.
create or replace function bulk_delete_list_members (list_ids bigint [], contact_ids bigint [])
returns setof bigint
language PLPGSQL
as $$
begin
return query WITH deleted AS (
delete from list_members
where (list_id, contact_id) in (
select list_id, contact_id
from unnest(list_ids, contact_ids) as x(list_id, contact_id)
) returning *
) SELECT count(*) FROM deleted;
end;
$$;
I don't think this is possible, but another way to do this would be to write a PostgreSQL function and call it using .rpc().
Check out this discussion thread on GitHub: github.com/supabase/supabase/discussions/3419
Related
The table in question has ~30mio records. Using Entity Framework I write a LINQ Query like this:
dbContext.MyTable.FirstOrDefault(t => t.Col3 == "BQJCRHHNABKAKU-KBQPJGBKSA-N");
Devart DotConnect for Oracle generates this:
SELECT
Extent1.COL1,
Extent1.COL2,
Extent1.COL3
FROM MY_TABLE Extent1
WHERE (Extent1.COL3 = :p__linq__0) OR ((Extent1.COL3 IS NULL) AND (:p__linq__0 IS NULL))
FETCH FIRST 1 ROWS ONLY
The query takes about four minutes, obviously a full table scan.
However, handcrafting this SQL:
SELECT
Extent1.COL1,
Extent1.COL2,
Extent1.COL3
FROM MY_TABLE Extent1
WHERE Extent1.COL3 = :p__linq__0
FETCH FIRST 1 ROWS ONLY
returns the expected match in 200ms.
Question: Why is it so? I would expect the query optimizer to note that the right part is false if the parameter is not null, so why doesn't the first query hit the index?
Please set UseCSharpNullComparisonBehavior=false explicitly:
var config = Devart.Data.Oracle.Entity.Configuration.OracleEntityProviderConfig.Instance;
config.QueryOptions.UseCSharpNullComparisonBehavior = false;
If this doesn't help, send us a small test project with the corresponding DDL script so that we can investigate the issue.
Currently, I'm working with Postgraphile and I need to enforce permissions at data/field level.
For example, I have a carmodel table, with my query is something like:
{
carmodel
{
id
name
description
}
}
Well, in this table I have ids (1 = AUDI, 2 = GM, 3 = BMW)
The current user (on roles/claims) has permission only to see (1=AUDI/3=BMW)
There is a way to enforce permissions based on field data? And return only data filtered on the user permissions?
Yes; row-level security can define this declaratively. Something like:
create policy audi_bmw on carmodel for select using (
id in (1, 3)
);
I'm guessing this permission comes from another table though; so it might be more like:
create policy audi_bmw on carmodel for select using (
id in (
select car_model_id
from user_carmodel_permissions
where user_id = current_user_id()
)
);
assuming you already have a current_user_id function, something like:
create function current_user_id() returns int as $$
select nullif(current_setting('jwt.claims.user_id', true), '')::int;
$$ language sql stable;
Check out our row level security cheatsheet.
I have the function below
CREATE OR REPLACE FUNCTION BUTCE_REPORT_Fun (birim_id IN VARCHAR2)
RETURN sys_refcursor
IS
retval sys_refcursor;
BEGIN
OPEN retval FOR
select *
from ifsapp.butce_gerceklesme
WHERE budget_year = '2018'
AND USER_GROUP = birim_id ;
RETURN retval;
END BUTCE_REPORT_Fun;
and am trying to execute the function this way
SELECT * from table(IFSAPP.BUTCE_REPORT_FUN('3008'))
the line above generates this exception
ora-22905 cannot access rows from a non-nested table item
to keep in mind that ifsapp.butce_gerceklesme is a view (which I do not think that it matters).
So how I can solve this. any help is appreciated.
Actually, am trying to create a function that returns rows from the view above according to the parameters provided. so if I can achieve that in another way that would be better.
Ref Cursors are for use in program calls: they map to JDBC or ODBC ResultSet classes. They can't be used as an input to a table() call. Besides, there is no value in calling your function in SQL because you can simply execute the embedded query in SQL.
the main table is huge and the inner query assigned to USER_GROUP is selected every time
So maybe what you want is subquery factoring AKA the WITH clause?
with ug as (
select con2.CODE_PART_VALUE
from IFSAPP.ACCOUNTING_ATTRIBUTE_CON2 con2
where COMPANY = 'XYZ'
and ATTRIBUTE = 'ABC'
and CODE_PART = 'J'
and con2.ATTRIBUTE_VALUE=407
AND rownum = 1
)
select *
from ifsapp.butce_gerceklesme t
join ug on t.USER_GROUP = ug.CODE_PART_VALUE
WHERE t.budget_year = '2018'
Tuning queries on StackOverflow is a mug's game, because there are so many things which might be responsible for sub-optimal performance. But as a rule of thumb you should try to tune the whole query. Encapsulating a part of it in PL/SQL is unlikely to improve response times, and indeed may degrade them.
I'm using MySQL and have a table of 9 million rows and would like to quickly check if a record (id) exists or not.
Based on some research it seems the fastest way is the following sql:
SELECT EXISTS(SELECT 1 FROM table1 WHERE id = 100)
Source: Best way to test if a row exists in a MySQL table
How can I write this using Laravel's query builder?
Use selectOne method of the Connection class:
$resultObj = DB::selectOne('select exists(select 1 from your_table where id=some_id) as `exists`');
$resultObj->exists; // 0 / 1;
see here http://laravel.com/docs/4.2/queries
Scroll down to Exists Statements, you will get what you need
DB::table('users')
->whereExists(function($query)
{
$query->select(DB::raw(1))
->from('table1')
->whereRaw("id = '100'");
})
->get();
This is an old question that was already answered, but I'll post my opinion - maybe it'll help someone down the road.
As mysql documentation suggests, EXISTS will still execute provided subquery. Using EXISTS is helpful when you need to have it as a part of a bigger query. But if you just want to check from your Laravel app if record exists, Eloquent provides simpler way to do this:
DB::table('table_name')->where('field_name', 'value')->exists();
this will execute query like
select count(*) as aggregate from `table_name` where `field_name` = 'value' limit 1
// this is kinda the same as your subquery for EXISTS
and will evaluate the result and return a true/false depending if record exists.
For me this way is also cleaner then the accepted answer, because it's not using raw queries.
Update
In laravel 5 the same statement will now execute
select exists(select * from `table_name` where `field_name` = 'value')
Which is exactly, what was asked for.
I have a an sqlite database with the table test. Several processes are accessing this database from bash. The table has the following fields:
CREATE TABLE mytable (id NUMERIC,
start JULIAN,
finish JULIAN)
I obtain an unique id by:
id=$(sqlite test.db <<EOF
BEGIN EXCLUSIVE;
SELECT id FROM mytable WHERE start IS NULL ORDER BY RANDOM() LIMIT 1;
COMMIT;
EOF
)
My question is, how can update the field start with:
UPDATE mytable set start=julianday('now') where id="SELECTED ID FROM ABOVE";
In the same statement?
Based on the comments that you supplied above, my solution would look something like follows (in perl with a raw DBI connection, also i didn't do a lot of error checking or anything either, something that you should probably do):
my $dbh = DBI->connect(...);
$dbh->do("BEGIN EXCLUSIVE");
my $stm = $dbh->prepare("SELECT id FROM mytable WHERE start IS NULL ORDER BY RANDOM() LIMIT 1");
$stm->execute();
my $row = $stm->fetchrow_hashref();
my $id = undef;
if ( $row ) {
$id = $row->{ID};
my $ustm = $dbh->prepare("UPDATE mytable set start=julianday('now') where id=?");
$ustm->execute($id);
}
$dbh->do("COMMIT");
# Still have the id at this point.