SqlQuery one named placeholders several times - c++

I tried
QSqlQuery query;
query.prepare("DELETE FROM names WHERE id_col = :ID OR id_parent = :ID");
query.bindValue(":ID", idVal);
query.exec();
assuming that idVal will be binded two times, but executing this query only rows with id_parent = idVal is deleted, with id_col = idVal remains undeleted. So only second time idVal was binded to the query.
When I rewrite it to
QSqlQuery query;
query.prepare("DELETE FROM names WHERE id_col = ? OR id_parent = ?");
query.bindValue(0, idVal);
query.bindValue(1, idVal);
query.exec();
everything worked as expected.
Is it a way to use one named placeholders several time in QSqlQuery?

From the QSqlQuery::bindValue() documentation:
Values cannot be bound to multiple locations in the query, eg:
INSERT INTO testtable (id, name, samename) VALUES (:id, :name, :name)
Binding to name will bind to the first :name, but not the second.
The last sentence appears to be slightly wrong as it looks like it binds to the second :name, but either way, this clearly states what you are trying to achieve is not supported by Qt.
Your options are to stick with the workaround you already have, or use the solution provided by Mahmoud Gamal in the comment to your question.

To see what query was actually executed, you can use QSqlQuery::executedQuery().
And you should explicitly set values for placeholders:
QSqlQuery query;
query.prepare("DELETE FROM names WHERE id_col = :ID_COL OR id_parent = :ID_PAR");
query.bindValue(":ID_COL", idVal);
query.bindValue(":ID_PAR", idVal);
query.exec();
Also it will be useful if you will need refactoring in future.

Try this first do:
select * from names where :ID in
((select id_col FROM names WHERE id_col = :ID)
OR
(select id_parent FROM names WHERE id_parent = :ID)
);
if the above select returned the right data then use the following as your query:
delete from names where :ID in
((select id_col FROM names WHERE id_col = :ID)
OR
(select id_parent FROM names WHERE id_parent = :ID)
);

Related

How is it possible to map column names from a Doctrine sql query?

I created a query with query builder like this:
$qb = $em->createQueryBuilder();
$qb->select(['u.id', 'u.name'])
->from(User::class, 'u')
->where('u.active = 1')
;
$sql = $qb->getQuery()->getSql();
The result looks like this:
SELECT u1_.user_id as s1, u1_.full_name as s2 FROM users u1_ WHERE u1_.is_active = 1
I would like to execute it as a native query, but I have to find out, how to map s1, s2 to id, name.
you have to use as inside your select
using your example =>
$qb = $em->createQueryBuilder();
$qb->select(['u.id as s1', 'u.name as s2'])
->from(User::class, 'u')
->where('u.active = 1');
$sql = $qb->getQuery()->getSql();
this maps id to s1 and name as s2
Not sure I understand your question but if you want to run a native query with, in the result, the columns id and name, you can replace them in the query, they're aliases so they can be anything you want :
SELECT u.user_id as id, u.full_name as name FROM users u WHERE u.is_active = 1

AWS error: Invalid operation: table name "?" specified more than once;

the below code works very well in SQL Server 2012, But when I use it in AWS amazon web service will give me a error "Amazon Invalid operation: table name "#t" specified more than once;"
CREATE TABLE #t (store_id varchar(20),city varchar(20),[state] varchar(20));
INSERT INTO #t VALUES
('22', 'new', 'NY'),
('22', null, null),
('22', null, null),
('33', null, null),
('33', 'LA', 'CA')
;
SELECT DISTINCT store_id, city, [state]
INTO #unique
FROM #t WHERE city IS NOT NULL;
;
UPDATE #t
SET city = #unique.city, [state] = #unique.[state]
FROM #unique
INNER JOIN #t
ON #unique.store_id = #t.store_id
WHERE #t.city IS NULL
Does anyone know why and modify my code? Thank you.
Here you go
UPDATE #t
SET city = #unique.city, [state] = #unique.[state]
FROM #unique
WHERE #unique.store_id = #t.store_id
AND #t.city IS NULL
Redshift does not need target table in FROM clause but in case if you need to specify it you need to alias it.
UPDATE #t
SET city = #unique.city, [state] = #unique.[state]
FROM #unique
JOIN #t t1
ON #unique.store_id = t1.store_id
WHERE t1.city IS NULL
From documentation
If you need to include the target table of the UPDATE statement in the list, use an alias.
https://docs.aws.amazon.com/redshift/latest/dg/r_UPDATE.html

Power Query - Add Column CountIF across two tables ie =COUNTIF(People[CityId],[#Id])

I have two tables in PowerQuery City and People.
CITY
Id, Name
1, Brisbane
2, Sydney
3, Melbourne
PEOPLE
Id, Name, CityId
1, Jay, 1
2, Sam, 2
3, Paul, 1
4, Sarah, 3
I'd like to add a column to City that shows a count of how many people belong to that city. So far I have:
Table.AddColumn(City, "People.Count", each
Table.RowCount(
Table.SelectRows(
People,
each [CityId] = [Id]
)
)
)
This returns all zeros in the new column. If I replace [Id] with 1 then I get 2.
It appears the [] references the value on the current row but on the same table. Is there a way I can write it as
Table.AddColumn(City, "People.Count", each
Table.RowCount(
Table.SelectRows(
People,
each People[CityId] = City[Id]
)
)
)
In Excel this would be as basic as
=COUNTIF(People[CityId],[#Id])
and then pulled down the new column in PEOPLE (as per attached .xlsx)
Seems simple enough but absolutely stuck! Eeek.
I would build a Query that starts from PEOPLE, and then Groups By City and calculates a Count.
Then I would Merge the CITY query with that new Query and expand the Count column.
No code or formulas are required - it's actually simpler than Excel formulas.
Ah, now I see what you're after. There's a nifty trick to do it with a simple column:
= Table.AddColumn(City, "People.Count", each let Id=[Id] in Table.RowCount(Table.SelectRows(People, each [CityId] = Id)))
You need to define the column name as a variable in order to "leave" the current "context" you're in (People's table).
There are other answers about how to write this differently, but the most general solution here is probably to remove the nested each syntax.
It might be helpful to see that your query
Table.AddColumn(
City,
"People.Count", each
Table.RowCount(Table.SelectRows(
People,
each [CityId] = [Id])))
is syntactic sugar for this rewritten version. In the _[CityId] = _[Id] expression, the _ variable is bound the innermost parameter, and the outermost _ isn't used:
Table.AddColumn(
City,
"People.Count", (_) =>
Table.RowCount(Table.SelectRows(
People,
(_) => _[CityId] = _[Id])))
If you ever have nested each expressions, I'd change the outer each to a function with a real variable name, like this:
Table.AddColumn(
City,
"People.Count", (CityRow) =>
Table.RowCount(Table.SelectRows(
People,
each [CityId] = CityRow[Id])))

Why can't I use the same cfqueryparam in two locations in the same query when using CFScript?

I'm not sure if I am doing something wrong, but it seems that you can not use a cfqueryparam more than once in a single query if you write it in CFScript.
This behavior is not consistent with CFML. I just re-wrote a similar query from CFML to CFScript and I'm getting the following error: cfsqlparam 'id' is not defined
local.query = new Query();
local.query.setSql("
SELECT id
FROM myTable
WHERE myTable.id = :id OR myTable.parentId = :id
");
local.query.addParam(name="id", cfsqltype="CF_SQL_INTEGER", value=arguments.id, maxlength=10);
local.query.execute().getResult();
If I take out the OR myTable.parentId = :id it works perfectly well. Do I have to create a param for every location I intend to use one?
If it was a CFQuery you would have one cfqueryparam for each value:
where myTable.id = <cfqueryparam... value="#arguments.id#" />
or myTable.parentid = <cfqueryparam ... value="#arguments.id#" />
so I'm guessing you need to do the same thing in script:
local.query.setSql("
SELECT id
FROM myTable
WHERE myTable.id = :id OR myTable.parentId = :pid ");
local.query.addParam(name="id", cfsqltype="CF_SQL_INTEGER",value=arguments.id,maxlength=10);
local.query.addParam(name="pid",cfsqltype="CF_SQL_INTEGER",value=arguments.id,maxlength=10);
As for the question "why can't the one addParam address both placeholders" I'm guessing it comes down to how the query is parsed by ColdFusion - because you specify two param placeholders the parser probably expects to find two params defined.

Nested statements in sqlite

I'm using the sqlite3 library in c++ to query the database from *.sqlite file. can you write a query statement in sqlite3 like:
char* sql = "select name from table id = (select full_name from second_table where column = 4);"
The second statement should return an id to complete the query statement with first statement.
Yes you can, just make sure that the nested query doesn't return more than one row. Add a LIMIT 1 to the end of the nested query to fix this. Also make sure that it always returns a row, or else the main query will not work.
If you want to match several rows in the nested query, then you can use either IN, like so:
char* sql = "select name from table WHERE id IN (select full_name from second_table where column = 4);"
or you can use JOIN:
char* sql = "select name from table JOIN second_table ON table.id = second_table.full_name WHERE second_table.column = 4"
Note that the IN method can be very slow, and that JOIN can be very fast, if you index on the right columns
On a sidenote, you can use SQLiteadmin (http://sqliteadmin.orbmu2k.de/) to view the database and make queries directly in it (useful for testing etc).