Is there any way to execute a dynamic query in bigquery? - sql

Folks, I need to do a dynamic select in a table, using the variable after from, like this:
SELECT * FROM #table.
If anyone can do this otherway, please help!
tks!
I'm using this query below:
DECLARE id INT64;
DECLARE contador INT64 DEFAULT 1;
DECLARE name_table STRING;
DECLARE query STRING;
CREATE OR REPLACE TABLE `crm-prod-254714.work.controle_tabelas`
AS
SELECT DISTINCT CONCAT('`', table_catalog, '.', table_schema, '.', table_name, '`') as tabela
,ROW_NUMBER() OVER() AS ROWID
FROM ntk.INFORMATION_SCHEMA.TABLES;
SET id = (SELECT MAX(ROWID) FROM `crm-prod-254714.work.controle_tabelas`);
WHILE (contador <= id) DO
SET name_table = (SELECT tabela FROM `crm-prod-254714.work.controle_tabelas` WHERE rowid = 1);
SET QUERY = CONCAT('SELECT * FROM ', name_table, ';');
EXECUTE QUERY;
SET contador = contador+1;
END WHILE

As of 5/20/2020, BigQuery released dynamic SQL feature for you to achieve the goal.
Dynamic SQL is now available as a beta release in all BigQuery regions. Dynamic SQL lets you generate and execute SQL statements dynamically at runtime. For more information, see EXECUTE IMMEDIATE.
For your scenario, you only need to make change to one line:
EXECUTE QUERY;
=>
EXECUTE IMMEDIATE QUERY;

Related

postgres sql / dbweaver - Using a variable for tablename?

One of the SQL Queries use the same table name again and again -
Example -
select
rr.jdoc as child_node, json_agg(parent_rr.jdoc)::jsonb as parent_node , array_length(array_agg(parent_rr.jdoc)::jsonb[], 1) as count
from MYTABLE rr, MYTABLE parent_rr
where
parent_rr.jdoc #> (rr.jdoc->'somefield')::jsonb
group by rr.jdoc
UNION
select rr.jdoc, NULL as parent_id, null as pcount
from MYTABLE rr where
not (rr.jdoc ?? 'somefiled')
and ((rr.jdoc->'crazyfiled'->>'doublecrazyfiled')<>'gotyou')
You can see the same MYTABLE is used 3 times. The thing is, I have to run the same query for different tables i.e the MYTABLE substituted.
So I am trying to find - if anything like below is possible -
SET TABLENAME=CUS_DELTA --//then use the above like -
select * from $TABLENAME;
I am using postgres 13.5 with DBeaver for running the queries.
If not SQL, does DBeaver provide any such means.
If SQL can not support it, I am ok to use Dynamic SQL / PL SQL (though i have not idea about these) - if its not going to be too complicate for the above case. But I am not aware about the code, so request to share the same through an answer.
Read this article about Dynamic SQL carefully. Example from the docs:
EXEC SQL BEGIN DECLARE SECTION;
const char *stmt = "INSERT INTO test1 VALUES(?, ?);";
EXEC SQL END DECLARE SECTION;
EXEC SQL PREPARE mystmt FROM :stmt;
...
EXEC SQL EXECUTE mystmt USING 42, 'foobar';
Basically this way you can simply pass values. Now, your values are dynamic as well, but no worries. Declare your tablename as varchar and SELECT tbname INTO yourvariable FROM sometable. Then you can pass this variable to your dynamic query.
EDIT:
Minimalistic example:
Setting a variable to hard-coded value
SET TABLENAME = 'CUS_DELTA';
Setting a variable to a dynamic table name
SELECT tbname
INTO TABLENAME
FROM yourtable
And then let's use our TABLENAME variable like this:
EXEC SQL BEGIN DECLARE SECTION;
const char *stmt = "SELECT * FROM ?";
EXEC SQL END DECLARE SECTION;
EXEC SQL PREPARE mystmt FROM :stmt;
EXEC SQL EXECUTE mystmt USING TABLENAME;
The above is untested.

How to create a reference value in Oracle SQl Developer

I use basic sql querying for my day to day work, but I regularly find myself needing to run queries in different tables using the same where clauses.
What I would ideally like to do is locally set a value to a name, for example:
traderef = ABCD1234. It's kind of like Defining a name in excel.
and then use 'traderef' in my queries,
select * from table1 where tranid = traderef
select * from table2 where tranid = traderef and otherattr = 'xyz1'
I only have query access to the dbs that i use, i have tried to google results, and found some info re SET
TIA
Declare a bind variable using the SQL/Plus and SQL Developer command VARIABLE name data_type and assign it a value using EXECUTE (or a PL/SQL anonymous block) and then use it in your queries:
VARIABLE traderef VARCHAR2(20)
EXEC :traderef := 'ABCD1234';
SELECT * FROM table1 WHERE tranid = :traderef;
SELECT * FROM table2 HWERE tranid = :traderef AND otherattr = 'xyz1';

db2 use query result in variable

i want to use the result of a query as an input in another query.
What might make it difficult: The variable is the schema in the database.
CREATE or replace VARIABLE myschema varchar(15) ;
set myschema = (select owner from syscat.tables where tabname = 'xyz');
select count(name) as result from myschema.USR02 where USTYP = 'A';
DROP VARIABLE myschema;
This is my last try, after i failed using declare.
But i get an error, because "myschema" is used as a string, and of course there is no schema with name "myschema". The result of the first query is not used.
If I just run the first two lines, i get the schemaname as result. Do i have to mark the variable in a special way? The goal is just the result of the query in line 3 by using the dynamic value of "myschema".
Unfortunately, you have to use dynamic SQL (forming a custom SQL query through string manipulation) if you want to deal with table, schema, or column names dynamically:
This is the basic idea:
execute immediate 'select * from ' || myschema || '.USR02';
However, you can't just run a bare select in dynamic SQL; you have to put the result in something. And the whole thing must be in a compound SQL block. So the full example would look something like this (simplified query for space).
This query assumes that a table called "result" exists to store the result you are returning.
begin
declare myschema varchar(100) default '';
set myschema = (select owner from syscat.tables where tabname = 'xyz');
execute immediate 'insert into result select count(*) from ' || myschema || '.USR02';
end
select * from result;
Note that within the block, you can simply declare a variable (as shown in my example). So you don't have to declare a global variable for this purpose, unless you want it to persist beyond this one statement.

how to incorporate dynamic column name in sql query

I have a table, which has columns, say
Week1,Week2, Week3 and so on.
I have a stored procedure, and based on the number input, i want to select that column.
Example, if input is 4 then I want to make the query,
select *
from table_name
where Week4=<something>
Is there any way to do this other than using dynamic query? Because this dynamic thing will be just a small part of a huge query.
The comments about normalization are right, but if you have no choice, you can use "or" clauses:
declare #inputvalue int;
set #int = 1;
select *
from <table>
where (week1 = <something> and #inputvalue = 1)
or (week2 = <something> and #inputvalue = 2)
or (week3 = <something> and #inputvalue = 3)
or (week4 = <something> and #inputvalue = 4)
This will be very slow if the tables are of any size, as you won't be using any indexes. I wouldn't suggest doing this unless you're absolutely unable to change the table structure.
I realize this isn't what you asked for, but I figured I'd point out to some people who find this what you mean by doing this as a dynamic query.
You'd just write a procedure and hold the field name in there. Assuming that the naming standard is the same, so the input value would be the week# (1,2,7,27, 123, etc.) and the field name would directly correspond (Week1, Week2, Week7, Week27, Week123, etc.)
create or replace procedure myweek(week_in varchar2)
is
dyn_sql varchar2(1000);
begin
dyn_sql := 'select * from table_name where week'||week_in||' = ''something;'' '
execute immediate dyn_sql;
end;
/
Then to call it you'd just do something like :
exec myweek(27); and it would generate the sql:
select * from table_name where week27 = 'something';

Finding number of columns returned by a query

How can I get the number of columns returned by an SQL query using SQL Server?
For example, if I have a query like following:
SELECT *
FROM A1, A2
It should return the total number of columns in table A1 + total number of columns in table A2. But the query might be more complicated.
Here is one method:
select top 0
into _MYLOCALTEMPTABLE
from (your query here) t
select count(*)
from Information_Schema.Columns c
where table_name = '_MYLOCALTEMPTABLE'
You can do something similar by creating a view.
You didn't specify your SQL Server version but I'm assuming it's not 2012. However, future readers of this question might be on 2012+ so I'm posting this answer for them.
SQL Server 2012 provides a set of procedures to provide more meta-data about queries and parameters. In this case, the stored procedure sp_describe_first_result_set will provide a handy tabular form.
There is also a DMO function, sys.dm_exec_describe_first_result_set, to provide similar content which is what you'd want to use in your example
DECLARE
-- Your query goes here
#query nvarchar(4000) = N'SELECT * FROM mdm.tblStgBatch AS TSB';
-- Tabular results
EXECUTE sys.sp_describe_first_result_set #tsql = #query;
-- Simple column count
SELECT
COUNT(1) AS column_count
FROM
sys.dm_exec_describe_first_result_set(#query, NULL, 0);
The new metadata discovery options are replacing FMTONLY which is how one would solve this problem prior to 2012. My TSQL chops are apparently not strong enough to do anything useful with it and instead I'd have to bail out to a .NET language to work with the output of FMTONLY.
SET FMTONLY ON;
SELECT *
FROM A1, A2;
SET FMTONLY OFF;
Try this;
--Insert into a temp table (this could be any query)
SELECT *
INTO #temp
FROM [yourTable]
--Select from temp table
SELECT * FROM #temp
--List of columns
SELECT COUNT(name) NumOfColumns FROM tempdb.sys.columns WHERE object_id =
object_id('tempdb..#temp');
--drop temp table
DROP TABLE #temp
Ugly I know:
SELECT COUNT(*) +
(
SELECT COUNT(*)
FROM information_schema.columns
WHERE table_name = 'A1'
)
FROM information_schema.columns
WHERE table_name = 'A2'