List all values ​in each SQL table - sql

I need to make a generic listing that will bring me all the values, ​​I have in the bank, every bank line.
My application needs to read information that changes and transits in the bank.

If you want to display all tables values/data in your Database without writing a select statement for each table you can use below SQL:
Try like this:
DECLARE #sqlText VARCHAR(MAX)
SET #sqlText = ''
SELECT #sqlText = #sqlText + ' SELECT * FROM ' + QUOTENAME(name) + CHAR(13) FROM sys.tables
EXEC(#sqlText)

Related

Adding a table variable in Dynamic SQL

I am a beginner in Dynamic SQL and trying to write a dynamic sql code in which I need to include a table variable .When I try to include the table variable I am getting an error saying that I need to include the Static variable.
Below is just part of the code
DECLARE #NAMES TABLE (name varchar)
DECLARE #fields varchar(max);
.
.
.
Select #fields=FROM sys.columns
WHERE object_id=object_id('dbo.employees')
order by name
SET #SQL=''
SET #SQL='Select '+ #fields
SET #SQL=#SQL + ' from dbo.test()'
SET #SQL = #SQL + ' WHERE name IN'
SET #SQL= #SQL + '(Select name from '
SET #SQL=#SQL + #NAMES +')'
To start with, your SELECT to get the column names won't work at all. You need something like this:
DECLARE #fields nvarchar(max);
SET #fields = N'';
SELECT #fields += CASE WHEN LEN(#fields) = 0 THEN N'' ELSE N', ' END + name
FROM sys.columns
WHERE object_id=object_id('dbo.employees')
ORDER BY column_id
PRINT #fields;
I'm honestly not sure what the rest of your SQL is trying to do... it's trying to select the fields from the employee table from the return of a table-valued function called test()? Where the 'name' column from that test() result set is in ... what? You'll need to be a lot more clear before I can give you a complete answer. One major problem is that you've never actually filled your table variable with anything, so ... I have no idea what you're going for. Knowing the definition of the Test() function would also be helpful.
But at least the above will give you the #fields variable set correctly to the list of columns in the table dbo.employee.
When doing Dynamic SQL, it really helps to write out the end resulting SQL you want, and then identify what parts of that SQL should be filled in by variable data, and work backwards. It's then a lot easier to construct your SQL to build your dynamic SQL.
You need to include the tablevariable logic to dynamic sql
--You need to load #names inside dynamic sql
DECLARE #fields varchar(max);
.
.
.
Select #fields=FROM sys.columns
WHERE object_id=object_id('dbo.employees')
order by name
SET #SQL='DECLARE #NAMES TABLE (name varchar); '
SET #SQL +=' Select '+ #fields
SET #SQL=#SQL + ' from dbo.test()'
SET #SQL = #SQL + ' WHERE name IN'
SET #SQL= #SQL + '(Select name from '
SET #SQL=#SQL + ' #NAMES )'
Or you can load into temp table and access the temptable inside dynamic sql. This means you will be loading temptable like #names and then use that in dynamic sql...

Update data in a SQL Server temp table where the column names are unknown

In a stored procedure I dynamically create a temp table by selecting the name of applications from a regular table. Then I add a date column and add the last 12 months. The result looks like this:
So far so good. Now I want to update the data in columns by querying another regular table. Normally it would be something like:
UPDATE ##TempTable
SET [columName] = (SELECT SUM(columName)
FROM RegularTable
WHERE FORMAT(RegularTable.Date,'MM/yyyy') = FORMAT(##TempMonths.x,'MM/yyyy'))
However, since I don't know what the name of the columns are at any given time, I need to do this dynamically.
So my question is, how can I get the column names of a temp table dynamically while doing an update?
Thanks!
I think you can use something like the following.
select name as 'ColumnName'
from tempdb.sys.columns
where object_id = object_id('tempdb..##TempTable');
And then generate dynamic sql using something like the following.
DECLARE #tableName nvarchar(50)
SET #tableName = 'RegularTable'
DECLARE #sql NVARCHAR(MAX)
SET #sql = ''
SELECT #sql = #sql + ' UPDATE ##TempTable ' + CHAR(13) +
' SET [' + c.name + '] = (SELECT SUM([' + c.name + ']) ' + CHAR(13) +
' FROM RegularTable' + CHAR(13) +
' WHERE FORMAT(RegularTable.Date,''MM/yyyy'') = FORMAT(##TempMonths.x,''MM/yyyy''));' + CHAR(13)
from tempdb.sys.columns c
where object_id = object_id('tempdb..##MyTempTable');
print #sql
-- exec sp_executesql #sql;
Then print statement in above snippet shows that the #sql variable has the following text.
UPDATE ##TempTable
SET [Test Application One] = (SELECT SUM([Test Application One])
FROM RegularTable
WHERE FORMAT(RegularTable.Date,'MM/yyyy') = FORMAT(##TempMonths.x,'MM/yyyy'));
UPDATE ##TempTable
SET [Test Application Two] = (SELECT SUM([Test Application Two])
FROM RegularTable
WHERE FORMAT(RegularTable.Date,'MM/yyyy') = FORMAT(##TempMonths.x,'MM/yyyy'));
So now, you use sp_exec to execute the updates as follows (un-comment it from above snippet).
exec sp_executesql #sql;
If it's a 1 time UPDATE you can PRINT the dynamic SQL statement (as shown above) and then execute it in the SSMS Query Windows.
I recommend you use the print statement first to make sure the UPDATE statements generated are what you want, and then do the sp_executesql or run the printed UPDATE statement in the query window.

Is there a way to replace a character or string in all fields without writing it for each field?

I will warn you up front, this question borders on silly, but I'm asking anyway.
The impetus for my question is creating a csv from a query result and some of the fields containing commas already. Obviously, the csv doesn't know any better and just merrily jacks up my good mood by having some stragglers in non-field columns.
I know I can write
Replace(FieldName, OldChar, NewChar)
for each field, but I'm more curious than anything if there's a shortcut to replace them all in the query output.
Basically what I'm looking for (logically) is:
Replace(AllFields, OldChar, NewChar)
I don't know all of the SQL tricks (or many of them), so I thought maybe the SO community may be able to enlighten me...or call me nuts.
There is no SQL syntax to do what you describe, but as you've seen there are many ways to do this with dynamic SQL. Here's the way I prefer (this assumes you want to replace commas with pipe, change this as you see fit):
DECLARE #table NVARCHAR(511),
#newchar NCHAR(1),
#sql NVARCHAR(MAX);
SELECT #table = N'dbo.table_name',
#newchar = N'|', -- tailor accordingly
#sql = N'';
SELECT #sql = #sql + ',
' + QUOTENAME(name)
+ ' = REPLACE(CONVERT(NVARCHAR(MAX), ' + QUOTENAME(name) + '),'','','''
+ #newchar + ''')'
FROM sys.columns
WHERE [object_id] = OBJECT_ID(#table)
ORDER BY column_id;
SELECT #sql = N'SELECT ' + STUFF(#sql, 1, 1, '') + '
FROM ' + #table;
PRINT #sql;
-- EXEC sp_executesql #sql;
I feel your pain. I often have one-time type cleansing steps in ETL routines. I find a script like this helps when you need to remove some oddity from an import (rogue page breaks, whitespace, etc.):
declare #tableName nvarchar(100) = 'dbo.YourTable';
declare #col nvarchar(max);
-- remove quotes and trim every column, kill page breaks, etc.
;with c_Col (colName)
as ( select c.name
from sys.tables t
join sys.columns c on
c.object_id = t.object_id
where t.object_id = object_id(#tableName)
)
select #col = stuff(a.n, 1, 1, '')
from ( select top 100 percent
',' + c.colName + '= nullif(replace(replace(replace(rtrim(ltrim('+c.colName+ ')), ''"'', ''''), char(13), ''''), char(10), ''''), '''') '
from c_col c
for xml path('')
) as a(n)
declare #cmd nvarchar(max)
set #cmd = 'update ' + #tableName + ' set ' + #col
print #cmd;
--exec(#cmd);
If you are just looking to save yourself some typing for a one time query statement affecting all fields in a table then this is a trick I've used in the past.
First query the schema to produce a result set that returns all the field names in any table you specify. You can modify what I've provided here as a template but I've given the basic structure of an update statement around the field names.
select column_name + ' = Replace(' + column_name + ',OldChar,NewChar),'
from information_schema.columns
where table_name = 'YourTableName'
The result set comes back in query analyzer as a series of rows that you can highlight (by clicking on column name) and then copying and pasting right back into your query analyzer window. From there add your update statement to the beginning and where clause to the end. You'll also need to get rid of the one extra comma.
You can then re-run the query to produce the desire outcome.

Accessing 400 tables in a single query

I want to delete rows with a condition from multiple tables.
DELETE
FROM table_1
WHERE lst_mod_ymdt = '2011-01-01'
The problem is that, the number of table is 400, from table_1 to table_400.
Can I apply the query to all the tables in a single query?
If you're using SQL Server 2005 and later you can try something like this (other versions and RDMS also have similar ways to do this):
DECLARE #sql VARCHAR(MAX)
SET #sql = (SELECT 'DELETE FROM [' + REPLACE(Name, '''','''''') + '] WHERE lst_mod_ymdt = ''' + #lst_mod_ymdt + ''';' FROM sys.tables WHERE Name LIKE 'table_%' FOR XML PATH(''))
--PRINT #sql;
EXEC ( #sql );
And as always with dynamic sql, remember to escape the ' character.
This will likely fall over if you have say table_341 which doesn't have a lst_mod_ymdt column.

In SQL Server 2008, how should I copy data from database to another database?

I'm trying to write a stored procedure to copy a subset of data from one set of tables to an identical set of tables in a different database. The "source" database needs to be a parameter to the stored procedure.
I've struggled with this for two days now, and I thought I had a good solution:
Validate that the schemas are the same.
Create temporary "rmt" synonyms for the source tables using dynamic SQL.
Copy the data using INSERT INTO A SELECT * FROM rmtA WHERE <criteria>
Delete the synonyms.
This works pretty well for most tables, but for tables that contain an identity column, I'm forced not only to SET IDENTITY_INSERT ON & OFF, but even worse, I can't use SELECT *; I have to specify all the columns explicitly. This will be a nightmare if I add or delete columns later.
I've gotta get something out the door, so I'm going with this solution for now, but I'd like to think that there's a better solution out there somewhere.
Help?
It sounds like you're using dynamic SQL in your stored procedure, so you're ready to dynamically create your list of columns in the SELECT clause.
You can select from sys.columns to get the list of columns, and learn if the table has an identity column. Here's a query that shows the information you need to create the list of columns.
SELECT c.name, is_identity
FORM sys.columns c
WHERE object_id = object_id('MyTable')
In short, if is_identity is 1 for at least one column, you'll need to include the SET IDENTITY_INSERT. And, you would exclude any columns from the SELECT clause where is_identity = 1.
And, this approach will adapt to new columns you add to the tables.
Here's an example
DECLARE #TableName varchar(128) = 'MyTableName'
DECLARE #ColumnName varchar(128)
DECLARE #IsIdentity bit
DECLARE #TableHasIdentity bit = 0
DECLARE #sql varchar(2000) = 'SELECT '
-- create cursor to step through list of columns
DECLARE MyCurs CURSOR FOR
SELECT c.name, is_identity
FROM sys.columns c
WHERE object_id = object_id(#TableName)
ORDER BY column_id
-- open cursor and get first row
OPEN MyCurs
FETCH NEXT FROM MyCurs INTO #ColumnName, #IsIdentity
-- process each column in the table
WHILE ##FETCH_STATUS = 0
BEGIN
IF #IsIdentity = 0
-- add column to the SELECT clause
SET #sql = #sql + #ColumnName + ', '
ELSE
-- indicate that table has identity column
SET #TableHasIdentity = 1
-- get next column
FETCH NEXT FROM MyCurs INTO #ColumnName, #IsIdentity
END
-- cursor cleanup
CLOSE MyCurs
DEALLOCATE MyCurs
-- add FROM clause
SET #sql = LEFT(#sql, LEN(#sql)-1) + CHAR(13) + CHAR(10) + 'FROM ' + #TableName
-- add SET IDENTITY if necessary
IF #TableHasIdentity = 1
SET #sql = 'SET IDENTITY_INSERT ' + #TableName + ' ON' + CHAR(13) + CHAR (10)
+ #sql + CHAR(13) + CHAR (10)
+ 'SET IDENTITY_INSERT ' + #TableName + ' OFF'
PRINT #sql