postgres sql / dbweaver - Using a variable for tablename? - sql

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.

Related

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

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;

Store a database name in variable & then using it dynamically

I have a Table in my Database Which have name of all the Database of my Server
Table Look like
create Table #db_name_list(Did INT IDENTITY(1,1), DNAME NVARCHAR(100))
INSERT INTO #db_name_list
SELECT 'db_One ' UNION ALL
SELECT 'db_Two' UNION ALL
SELECT 'db_Three' UNION ALL
SELECT 'db_four' UNION ALL
SELECT 'db_five'
select * from #db_name_list
I have so many SP in my Database..Which uses multiple table and Join Them..
At Present I am using the SQL code like
Select Column from db_One..Table1
Left outer join db_two..Table2
on ....some Condition ....
REQUIREMENT
But I do not want to HARDCODE the DATABASE Name ..
I want store DataBase name in Variable and use that .
Reason :: I want to restore same Database with Different name and want to Run those SP..At Present we Cant Do ,Because I have used db_One..Table1
or db_two..Table2
I want some thing like ...
/SAMPLE SP/
CREATE PROCEDURE LOAD_DATA
AS
BEGIN
DECLARE #dbname nvarchar(500)
set #dbname=( SELECT DNAME FROM #db_name_list WHERE Did=1)
set #dbname2=( SELECT DNAME FROM #db_name_list WHERE Did=2)
PRINT #DBNAME
SELECT * FROM #dbname..table1
/* or */
SELECT * FROM #dbname2.dbo.table1
END
i.e using Variable Instead of Database name ..
But it thow error
"Incorrect syntax near '.'."
P.S This was posted by some else on msdn but the answer there was not clear & I had the same kind of doubt. So please help
You can't use a variable like this in a static sql query. You have to use the variable in dynamic sql instead, in order to build the query you want to execute, like:
DECLARE #sql nvarchar(500) = 'SELECT * FROM ' + #dbname + '.dbo.mytable'
EXEC(#sql);
There seem to be a couple of options for you depending on your circumstances.
1. Simple - Generalise your procedures
Simply take out the database references in your stored procedure, as there is no need to have an explicit reference to the database if it is running against the database it is stored in. Your select queries will look like:
SELECT * from schema.table WHERE x = y
Rather than
SELECT * from database.schema.table WHERE x = y
Then just create the stored procedure in the new database and away you go. Simply connect to the new database and run the SP. This method would also allow you to promote the procedure to being a system stored procedure, which would mean they were automatically available in every database without having to run CREATE beforehand. For more details, see this article.
2. Moderate - Dynamic SQL
Change your stored procedure to take a database name as a parameter, such as this example:
CREATE PROCEDURE example (#DatabaseName VARCHAR(200))
AS
BEGIN
DECLARE #SQL VARCHAR(MAX) = 'SELECT * FROM ['+#DatabaseName+'].schema.table WHERE x = y'
EXEC (#SQL)
END

How to extract part of SQL query from a table

Is it possible to to extract SQL queries that are saved in a table?
For example
select * from saved_queries
name | statement
queryname | 'select * from mytable where myfield = 'somevalue'
I would like to be able to do something like
select * from ( extractsomehow( 'select Statement from saved_queries where name = 'queryname') ).
Unfortunately I cannot use Java so I am restricted to SQL and XML there.
I am using Oracle 11g
If you can write a stored procedure, you could use execute immediate, something like this:
select statement into v_statement from saved_queries where ... ;
execute immediate v_statement;
Before you use dynamic SQL, think carefully about whether or not you actually need it.

check for zero rows in select query

My C program has an embedded sql query. This program runs on windows and queries the oracle database.
The query is similar to EXEC SQL SELECT ...
I need to add here a check to know if the query returns zero rows.
Basically I want to set a local valiable to know my query has returned no rows and
handle this condition accordingly.
How can I add it. I know that EXISTS statement can be used. But I am not getting
how do I use it in embedded sql.
Thanks for any help.
Use the sqlca struct
EXEC SQL include "sqlca.h"
#define NO_ROWS_FOUND (sqlca.sqlcode==1403)
EXEC SQL BEGIN DECLARE SECTION;
int val=0;
short ind=0;
EXEC SQL END DECLARE SECTION;
EXEC SQL
select value
int :val :ind
from mytable where rownum=1;
if(NO_ROWS_FOUND)
printf("No rows found\n");
Use SELECT COUNT(*) FROM ... and compare result to 0.

C# SQL Top as parameter

Trying to parameterize the value of TOP in my sql statement.
SELECT TOP #topparam * from table1
command.Parameters.Add("#topparam",SqlDbType.VarChar, 10).Value = somevalue.ToString();
This doesn't seem to work. Anyone have any suggestions?
Just to clarify, I don't want to use stored procedures.
In SQL Server 2005 and above, you can do this:
SELECT TOP (#topparam) * from table1
You need to have at least SQL Server 2005. This code works fine in 2005/8 for example ...
DECLARE #iNum INT
SET #iNum = 10
SELECT TOP (#iNum) TableColumnID
FROM TableName
If you have SQL Server 2000, give this a try ...
CREATE PROCEDURE TopNRecords
#intTop INTEGER
AS
SET ROWCOUNT #intTop
SELECT * FROM SomeTable
SET ROWCOUNT 0
GO
You could write an inline query:
EXEC 'SELECT TOP ' + #topparam + ' * FROM ... '
Parse it as an int and that will prevent a SQL injection attack.