DYnamic SQL examples - sql

I have lately learned what is dynamic sql and one of the most interesting features of it to me is that we can use dynamic columns names and tables. But I cannot think about useful real life examples. The only one that came into my mind is statistical table.
Let`s say that we have table with name, type and created_data. Then we want to have a table that in columns are years from created_data column and in row type and number of names created in years. (sorry for my English)
What can be other useful real life examples of using dynamic sql with column and table as parameters? How do you use it?
Thanks for any suggestions and help :)
regards
Gabe
/edit
Thx for replies, I am particulary interested in examples that do not contain administrative things or database convertion or something like that, I am looking for examples where the code in example java is more complicated than using a dynamic sql in for example stored procedure.

An example of dynamic SQL is to fix a broken schema and make it more usable.
For example if you have hundreds of users and someone originally decided to create a new table for each user, you might want to redesign the database to have only one table. Then you'd need to migrate all the existing data to this new system.
You can query the information schema for table names with a certain naming pattern or containing certain columns then use dynamic SQL to select all the data from each of those tables then put it into a single table.
INSERT INTO users (name, col1, col2)
SELECT 'foo', col1, col2 FROM user_foo
UNION ALL
SELECT 'bar', col1, col2 FROM user_bar
UNION ALL
...
Then hopefully after doing this once you will never need to touch dynamic SQL again.

Long-long ago I have worked with appliaction where users uses their own tables in common database.
Imagine, each user can create their own table in database from UI. To get the access to data from these tables, developer needs to use the dynamic SQL.

I once had to write an Excel import where the excel sheet was not like a csv file but layed out like a matrix. So I had to deal with a unknown number of columns for 3 temporary tables (columns, rows, "infield"). The rows were also a short form of tree. Sounds weird, but was a fun to do.
In SQL Server there was no chance to handle this without dynamic SQL.

Another example from a situation I recently came up against. A MySQL database of about 250 tables, all in MyISAM engine and no database design schema, chart or other explanation at all - well, except the not so helpful table and column names.
To plan for conversion to InnoDB and find possible foreign keys, we either had to manually check all queries (and the conditions used in JOIN and WHERE clauses) created from the web frontend code or make a script that uses dynamic SQL and checks all combinations of columns with compatible datatype and compares the data stored in those columns combinations (and then manually accept or reject these possibilities).

Related

Query all tables within a Snowflake Schema

Due to the way our database is stored, we have tables for each significant event that occurs within a products life:
Acquired
Sold
Delivered
I need to go through and find the status of a product at any given time. In order to do so I'd need to query all of the tables within the schema and find the record with the most up to date record. I know this is possible by union-ing all tables and then finding the MAX timestamp but I wonder if there's a more elegant solution?
Is it possible to query all tables by just querying the root schema or database? Is there a way to loop through all tables within the schema and substitute that into the FROM clause?
Any help is appreciated.
Thanks
You could write a Stored Procedure but, IMO, that would only be worth the effort (and more elegant) if the list of tables changed regularly.
If the list of tables is relatively fixed then creating a UNION statement is probably the most elegant solution and relatively trivial to create - if you plan to use it regularly then just create it as a View.
The way I always approach this type of problem (creating the same SQL for multiple tables) is to dump the list of tables out into Excel, generate the SQL statement for the first table using functions, copy this function down for all the table names and then concatenate all these statements in a final function. You can then just paste this text back into your SQL editor

one table with a lot of rows or a lot of tables with a view? on SQL Server

My question comes from what is more efficient when making queries and insert, since the number of registers(data) in my table will grow a lot.
I would like to know what is more efficient to do if all the data is placed within a single table or is the partition and through a View and trigger is more efficient to obtain and enter registers(data).
As already mentioned take a look at database normalization.
SQL is a way to work with relational databases and is built on the idea that we should have many tables that are linked with each other trough relationships. Thus I recommend multiple tables, because you will be able to reuse data (for example user name and surname) through specific IDs rather than copying that data each time a user performs some action on your platform and you need to insert or update some information.
Hope this helps!

Aliasing multiple columns using an expression in Oracle SQL Developer

In Oracle SQL Developer, is it possible to alias multiple column names as part of a SELECT statement using an expression (as opposed to manually specifying the aliases for each column)?
Specifically, I have a mapping table that stores the task-relevant subset of columns from a large data table. Each entry in the mapping table ties a data table column name to a human readable description. I want to select the data table columns listed in the mapping table and display them with the mapping table descriptions as the column headers, but WITHOUT manually typing in the column names and their human-readable aliases one-by-one. Is this possible?
The closest I've found to an answer online is this SO question which suggests what I want to do is NOT possible: Oracle rename columns from select automatically?
But, that question is from 2010. I'm hoping the situation has changed. Thank you for your help.
This still cannot be done with 100% native SQL. These overly-dynamic situations are usually best avoided; a little extra typing is generally better than adding
complicated code.
If you truly have an exceptional case and are willing to pay the price there is a way to do this. It doesn't use 100% natural SQL, but it could be considered "pure" SQL since it uses the Oracle Data Cartridge framework to extend the database.
You can use my open source project Method4 to run dynamic SQL in SQL. Follow the Github steps to download and install the objects. The code is painfully complicated but luckily you won't need to understand most of it. Only the simple changes below are necessary to get started on customizing column names.
Method4 Changes
Create a variable to hold the new column name. Add it to the declaration section of the function ODCITableDescribe, on line 12 of the file METHOD4_OT.TPB.
v_new_column_name varchar2(32);
Create a SQL statement to map the old column to the new column. Add this to line 31, where it will be run for each column.
--Get mapped column name if it exists. If none, use the existing name.
select nvl(max(target_column_name), r_sql.description(i).col_name)
into v_new_column_name
from column_names
where source_column_name = r_sql.description(i).col_name;
Change line 42 to refer to the new variable name:
substr(v_new_column_name, 1, 30),
Mapping Table
drop table column_names;
create table column_names
(
source_column_name varchar2(30),
target_column_name varchar2(30),
constraint column_names_pk primary key(source_column_name)
);
insert into column_names values('A1234', 'BETTER_COLUMN_NAME');
insert into column_names values('B4321', 'Case sensitive column name.');
Query Example
Now the column names from any query can magically change to whatever values you want. And this doesn't simply use text replacement; the columns from a * will also change.
SQL> select * from table(method4.query('select 1 a1234, 2 b4321, 3 c from dual'));
BETTER_COLUMN_NAME Case sensitive column name. C
------------------ --------------------------- ----------
1 2 3
Warnings
Oracle SQL is horrendously complicated and any attempt to build a layer on top if it has many potential problems. For example, performance will certainly be slower. Although I've created many unit tests I'm sure there are some weird data types that won't work correctly. (But if you find any, please create a Github issue so I can fix it.)
In my experience, when people ask for this type of dynamic behavior, it's usually not worth the cost. Sometimes a little extra typing is the best solution.

SELECT from table specified in another table - possible without dynamic SQL?

I've a database which contains several tables for various tables of different products. These products have unique part numbers across all tables.
To search across all tables, I've created a view which uses UNION ALL across all common fields in the tables.
Once a part has been identified, I need to select all the columns depending on the table the data resides in. The view includes a field that specifies the table the data was found in.
I'm not sure of the way to accomplish the last part:
CASE statement (I'm leaning towards this one at the moment)
Dynamic SQL (prefer not to use this, would involve SELECT * and other nasties)
SELECT in client side (client needs to select from arbitrary tables, require additional privileges, bad design?)
Alternative solution?
EDIT: Actually, IF statement is the only one that makes sense. Client shouldn't need access to the tables directly. Since the columns are different in each table anyway, might as well have a seperate statement for each table.
(I'd mark the question as answered, but I don't have enough reputation for that)
I am not sure whether i understood your question correctly.. my understanding is you have views which is selecting data from diffrent tables using union all.. you can give table name while creating view only
select "table1",table1.a,table1.b.. from table1
union all
select "table2", table2.a,table2.b ..... from table2
Actually, IF statement is the only one that makes sense. Client shouldn't need access to the tables directly. Since the columns are different in each table anyway, might as well have a seperate statement for each table.

Best way to compare contents of two tables in Teradata?

When you need to compare two tables to see what the differences are, are there any tools or shortcuts you use, or do you handcode the SQL to compare the two tables?
Basically the core features of a product like Red Gate SQL Data Compare (schemas for my tables typically always match).
Background: In my SQL Server environment, I created a stored procedure which inspects the metadata of the two tables/views, creates a query (as dynamic sql) which joins the two tables on the specified key columns, and compares data in the compare columns, reporting key differences and data differences. The query can either be printed and modified/copied or just excecuted as is. We are not allowed to create stored procedures in our Teradata environment, unfortunately.
Sounds like a data profiling tool such as Talend's Open Profiler would make the most sense at that point.
You could write a BTEQ statement that builds the query similar to your SQL Server stored procedure and then export the dynamically built SQL. You can then in turn run that inside of your BTEQ. It might get cumbersome, but with enough determination you could probably mock something up.
I dont know if this is the right answer you are searching for.
sel * from database_name1.table_name1
minus
sel * from database_name2.table_name2;
you can do the same by selecting specific columns. This will basically give the non existent rows from table2 which are in table1.
If you were not looking for this type of answer, please ignore this and continue.
Also you can select like below.
select
table1.keycol1,
table2.keycol2,
(table1.factcol1 - table2.factcol2) as diff
from table1
inner join
table2
on table1.keycol1 = table2.keycol1
and table1.keycol2 = table2.keycol2
where diff <> 0
This was just an analysis which can give an idea. Please ignore any syntactical and programmatical errors.
Hope this helps.