Perform query on multiple tables - sql

I need to apply the following query to 60+ tables:
UPDATE variable_table_name ab
SET elem_nr = ef.elem_nr
FROM ga_mit_elemnr ef
WHERE (ab.elem_nr NOT IN
(SELECT elem_nr
FROM strassenelemente cd)
OR ab.elem_nr IS NULL)
AND St_within(ab.geom, ef.geom)
Is there a way to automate this in PostgreSQL?

As far as I am aware it is not possible to do this in Plain SQL, however you could use PL/pgSQL to execute the query as dynamic command in a for loop and run this query against your 60+ tables. You can read about Pl/pgSQL here: https://www.postgresql.org/docs/9.6/plpgsql.html
Depending on your requirements you could also use other programming languages such as Python to dynamically execute SQL-statements as string.

After understanding the case, I would suggest using postgres partitioning mechanism
I.e have a master table and 60+ partitions, each partition will be attached to the master, and on ALTER TABLE you alter only the master table schema, and all the rest will be updated as well

Something like this..?
DECLARE #sql NVARCHAR(max)
SELECT #sql = N' '+ String_agg(Concat(N'
UPDATE ', CONVERT(NVARCHAR(max), Quotename(col_table_name)), N'
SET column1 = value1, column2 = value2...., columnN = valueN
WHERE [condition];'), N'' + CHAR(13) + CHAR(13))
FROM information_schema.tables
WHERE [condition]
EXEC (#sql)
Once you get the query, you can check the query by using the SELECT statement.
SELECT (#sql)
If the query is okay, then you can execute it.
EXEC (#sql)
Example: https://data.stackexchange.com/stackoverflow/query/1011376/

Related

Dynamic PIVOT query - How to save it in SQL Server?

I had to built a dynamic PIVOT in SQL Server as described in this article using the following script:
DECLARE #DynamicPivotQuery AS NVARCHAR(MAX)
DECLARE #ColumnName AS NVARCHAR(MAX)
--Get distinct values of the PIVOT Column
SELECT #ColumnName= ISNULL(#ColumnName + ',','')
+ QUOTENAME(Course)
FROM (SELECT DISTINCT Course FROM #CourseSales) AS Courses
--Prepare the PIVOT query using the dynamic
SET #DynamicPivotQuery =
N'SELECT Year, ' + #ColumnName + '
FROM #CourseSales
PIVOT(SUM(Earning)
FOR Course IN (' + #ColumnName + ')) AS PVTTable'
--Execute the Dynamic Pivot Query
EXEC sp_executesql #DynamicPivotQuery
It works great and it returns a dynamic table as expected.
However, I would like to be able to select it in an other query but can not find a proper way to do so:
A view does not work as it does not accept variables
A table valued function does not work as I don't know in advance the structure of the output table
A stored procedure does not work as I can not use it in a SELECT query
What would be the best solution to save this dynamic pivot query and be able to SELECT it afterwards?
Thank you
Sylvain
Oh. You can use temp table, my friend. The first, check the exists of temp table. And remember drop it at the end of query.
You could try to use the stored procedure and in that sp use the SELECT INTO in the dynamic pivot query and store in a temporary table (#myDynamicPivot).
Then you can use the temporary table in your next selects statements. Make sure you drop your table after using it.
Edit
I would consider moving that data that the pivot table is created against to a data warehouse and create an analysis database over it. This way you can query using the dimensions and the data will be much faster and it will be more optimized for storage and query.

SQL Server - select into from statement?

I have this query in SQL Server:
select column
from table_53;
Now, I want to get this 53 from another table, so what I want to do is something like this:
select column
from table_(select id from table2);
Is there any way to do this in SQL Server?
This is definitely not the way SQL thinks and works. Maybe your suggested approach can be mimicked by way of writing stored procedures in which you create SQL-statements which are then evaluated. However, this will not be very efficient.
A better approach would be to store the values of all your individual separate tables into one master table and mark them in a separate column tblid with their number (e.g. 53). Then you can always filter them from this master table by looking for this tblid.
You need dynamic sql query here.
declare #sqlQuery = 'select column
from table_(';
set #sqlQuery = #sqlQuery + 'select id from table2)';
EXEC (#sqlQuery)
Note :- One of cons of using dynamic sql query is sql injection. I would suggest to have better table structure or try to used parameterized query.
Yes, you can, but using something like this:
DECLARE #ID INT;
DECLARE #QUERY NVARCHAR(MAX);
SELECT #ID = ID FROM TABLE_2;
--IF #ID EQUALS 53 THEN
SET #QUERY = 'SELECT COLUMN FROM TABLE_' + CAST(#ID AS NVARCHAR(10));
-- #QUERY EQUALS TO 'SELECT COLUMN FROM TABLE_53'
EXEC (#QUERY);

How I can use a single stored procedure for data insertion in multiple tables in SQL Server 2008?

Suppose I have many tables in my database. Every time I will insert data in any table. So, can I use a single stored procedure for all my data insertion in every table, instead of writing one stored procedure for each table?
In this scenario, each time I will pass table name and parameters dynamically to the stored procedure. If yes, can anyone give some basic idea how to perform this? If any extra information is required, please ask.
Thanks and regards,
Rizwan Gazi.
You could work with dynamic SQL and build the insert statement on the fly. THIS IS NOT RECOMMENDED but it should solve the problem you're asking about.
(I haven't run this code, but you can see what is being accomplished here with building the insert string and then executing it)
In this procedure, you pass in the table name, columns and values you care about and fire it off in a row based operation. With some minor tweaks you would be able to make it set based as well.
create procedure dbo.TableInsert
#tablename varchar(100)
, #columnlist varchar(max)
, #valueslist varchar(max)
as
begin
declare #sql varchar(max)
set #sql =
'insert into ' + #tablename
+ '(' + #columnlist + ')'
+ ' VALUES (' + #valueslist + ')'
print(#sql)
sp_executesql (#sql)
end
go
Execution would look something like this:
exec dbo.TableInsert
#tablename = 'TestTable'
, #columnlist = 'col1, col2, col3'
, #valuelist = '1,2,3'
Text insert would be a little trickier in this version since you have to wrap it around in single quotes.
exec dbo.TableInsert
#tablename = 'TestTable'
, #columnlist = 'col1, col2, col3'
, #valuelist = '''1'',''2'',''3'''
You could do something using dynamic SQL to build a query and then run it using:
EXEC SP_EXECUTESQL(#SQL)
(Assuming MS SQL Server)
Not sure I'd recommend it though and will probably be a total nightmare to test and maintain. Having different sprocs would be easier to test and maintain going forward and would perform better as the different sprocs would have separate query plans.
If you are working in code you could use a ORM to deal with basic CRUD stuff.

Is there a quick way to check if ANY column is NULL?

I have a table with around 20 columns. Aside from typing out:
Where column1 is null OR column2 is null OR column3 is null etc...
Is there a quicker way to just check every column and see if any value is null and if so, return that record?
No. There are ways to code it quicker, but there are no shortcuts like you imply. Taken from an answer I gave on dba.stackexchange:
DECLARE #tb NVARCHAR(255), #sql NVARCHAR(MAX);
SET #tb = N'dbo.[table]';
SET #sql = N'SELECT * FROM ' + #tb + ' WHERE 1 = 0';
SELECT #sql = #sql + N' OR ' + QUOTENAME(name) + ' IS NULL'
FROM sys.columns
WHERE [object_id] = OBJECT_ID(#tb);
EXEC sp_executesql #sql;
You can find the column names using something like this:
SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.Columns where TABLE_NAME = <table_name>
Then, I would write a procedure using this, and that would loop through the entries in your table and the column names.
Source: http://codesnippets.joyent.com/posts/show/337
That depends on what quicker means.
If you mean quicker for SQL Server to execute, one thing you could do is write a trigger than updates a bit column that specifies if the entire row (other than the bit and primary key) are NULL. But, there should be a REAL good reason for this as it will impact your update performance. Indexes on those columns would help as well.
If you mean quicker to write, you could have SQL generate the where clause for you. But, unless you do this alot, it isn't worth the time in my opinion.
Teaching-to-fish-instead-of-giving-you-the-fish kind of answer here:
One way of doing it is by creating a Stored Procedure that assembles and runs a dynamic query.
The Stored procedure will:
have a Table name as input parameter.
query the meta data system tables for the specific table structure.
dynamically assemble a string (the actual query) with the OR statements for that table's columns.
run the assembled query and return the result.

SQL Dynamic SELECT statement from values stored in a table

I have been researching this for a couple of days and feel like I am going around in circles. I have basic knowledge of SQL but there are many areas I do not understand.
I have a table that stores the names and fields of all the other tables in my database.
tblFields
===================================================
TableName FieldName BookmarkName
---------------------------------------------------
Customer FirstName CustomerFirstName
Customer LastName CustomerLastName
Customer DOB CustomerDOB
I want to write a SELECT statement like the following but i am unable to get it work:
SELECT (SELECT [FieldName] FROM [TableName]) FROM tblFields
Is this possible? The application I have developed requires this for user customization of reports.
If i understand what you are trying to do, i think this will help you. It is not pretty and it works for SQL Server 2005 and above, but maybe this is what you are looking for:
declare #tableName nvarchar(100)
declare #sqlQuery nvarchar(max)
declare #fields varchar(500)
set #tableName = 'YourTableName'
set #fields = ''
select #fields = #fields + QUOTENAME(t.fieldname) + ',' from (
select distinct fieldname from tblfields where tablename = #tableName)t
set #sqlQuery = 'select ' + left(#fields, LEN(#fields)-1) + ' from ' + QUOTENAME(#tableName)
execute sp_executesql #sqlQuery
Edit: As Martin suggested, i edited so that the columns and tablename are using QUOTENAME
If I understand correctly what you are trying to do, you are probably better off doing this as two separate queries from your program. One which gets the fields you want to select which you then use in your program to build up the second query which actually gets the data.
If it must be done entirely in SQL, then you will need to tell us what database you are using. If it is SQL Server, you might be able to user a cursor over the first query to build up the second query which you then execute with the sp_executesql stored procedure. But doing doing it outside of SQL would be recommended.