Get current table name in query - sql

Is it possible to get table name in select statement?
Example:
SELECT Id, "Users" as TableName
FROM Users
I don't want to write "Users" manually but to determine it based on FROM statement.
I'm doing some migrations from one database to another (with different structure), and I have mapping table that stores old table names so that's why I need this (it's less error prone).

You can use following sub-query to get this information (works on SQL Server 2012+):
SELECT *,
(select object_name(ind.object_id)
from sys.fn_PhysLocCracker(%%physloc%%) plc
INNER JOIN SYS.DM_DB_DATABASE_PAGE_ALLOCATIONS(DB_ID(),null,null,null,null) ind
ON ind.allocated_page_file_id = plc.file_id
AND ind.allocated_page_page_id = plc.page_id) as table_name
FROM [your table]
It is painfully slow, caching on the side page allocation will speed things up.

Alternatively, if you want to do it for all tables, you can use following stored procedure:
USE [DB_NAME]
EXEC sp_msforeachtable 'SELECT Id, ''?'' AS [TableName] FROM ?'
Maybe it will be helpful for somebody :)

Related

How can I find a table in SQL Server 2016

How can I find a table in SQL Server 2016?
I could use this to find the table in the current database:
SELECT *
FROM sys.Tables
WHERE name LIKE '%App_Current_Seq_Num%'
The problem is, I have several databases on the server.
Please try with the below sql query.
select * from [YourDatabaseName].INFORMATION_SCHEMA.TABLES where TABLE_NAME LIKE '%App_Current_Seq_Num%'
sp_tables , sys.tables , information_schema.tables will only give you the list of tables from current selected database. Use the below undocumented stored procedure to run this code for each database, with each resultset showing the list of tables belonging to it.
sp_MSforeachdb 'SELECT "?" AS DB, * FROM [?].sys.tables WHERE name like ''%App_Current_Seq_Num%'''
Another option is to use dynamic SQL .
You can either do
use your_database_name
SELECT *
FROM sys.Tables
WHERE name LIKE '%App_Current_Seq_Num%'
or
SELECT *
FROM your_database_name.sys.Tables
WHERE name LIKE '%App_Current_Seq_Num%'
or if you want to search multiple databases at once use a union all clause.
Something like this:
SELECT * FROM database1.sys.Tables
UNION ALL
SELECT * FROM database2.sys.Tables
I used this and it worked perfectly:
USE Master
GO
EXEC sp_MSforeachdb
#command1='use ?; SELECT *
FROM sys.tables
WHERE name LIKE ''%App_Current_Seq_Num%'''
you can use SQL Search
it is a simple search control that you can use in sql server
to find tables/views/stored procedures and etc...
use fast free download from
https://www.red-gate.com/products/sql-development/sql-search/index

SQL using REPLACE on one of many columns

I have the following query:
SELECT * FROM MailingList
There are about 20+ columns in the MailingList table, one which is called Address. This column has some fields which contain commas, which I need to take out. So I updated my query to:
SELECT REPLACE(Address, ',', '') AS Address, * FROM MailingList
But now I have two Address columns. Is there a way to only display one Address column while still using the wildcard (*) for all the other columns?
There is not a way to do this, though listing the columns you want explicitly is a good idea anyway.
You can trick as following query:
Get the data into a temp table
Drop the cloumns that are not needed
Get results and drop temp table
SELECT *, REPLACE(Address, ',', '') AS Address2
INTO #TempTable
FROM MailingList
ALTER TABLE #TempTable
DROP COLUMN [Address]
SELECT * FROM #TempTable
DROP TABLE #TempTable
I agree with Shadow - avoid using the * wild card if you can...
I know listing out ALL of the columns in select statement for big tables is a pain so here is a quick short cut you may not be aware of: In SQL Server Management Studio, browse through the object explorer and find the table you want to select from (MailingList). Right-click it to view the context menu and choose "Script Table as" then "SELECT TO" then "New Query Editor Window". This will create a new select statement with each column spelled out. In the future, use this method to create select statements, queries, procedures, etc. rather then the * wildcard. Performance is better and it just looks nicer :-)
Then you can solve your alias issue with the replace function.

Rowcounts of all tables in a database in Netezza

I am migrating data from MS SQL to Netezza and so I need to find the row counts of all tables in a database (in Netezza). Any query for the same would be of an immense help to me as I'm completely new to this. Thanks in advance.
This query does it directly from _v_table:
SELECT TABLENAME, RELTUPLES FROM _V_TABLE where objtype = 'TABLE' ORDER BY RELTUPLES
something like this should work:
select 'select '||chr(39)||tablename||chr(39)||' as entity, count(1) from '||tablename||' union all'
from _v_table
where object_type ='TABLE';
copy/paste the result, remove the last "union all".
I have never used Netezza but googled and found:
http://www.folkstalk.com/2009/12/netezza-count-analytic-functions.html
SELECT dept_id,
salary,
COUNT(1) OVER() total_cnt
FROM Employees
If you don't know what tables that exists:
http://www.folkstalk.com/2009/11/netezza-system-catalog-views.html
select * from _v_table;
Another way to acquire the row counts for a table (if you have access to the operating system level) is to use the Netezza nz_get_table_rowcount command. You can enter, "nz_get_table_rowcount -h" to get all of the help text on this command, but the format is:
Usage: nz_get_table_rowcount [database]
Purpose: Perform a "SELECT COUNT(*) FROM ;" to get its true rowcount.
Thus, this script results in a full table scan being performed.
Inputs: The database name is optional. If not specified, then $NZ_DATABASE
will be used instead.
The table name is required. If only one argument is specified, it
will be taken as the table name.
If two arguments are specified, the first will be taken as the
database name and the second will be taken as the table name.
Outputs: The table rowcount is returned.
Use this command in a shell script to cycle through all of the tables within a database. Use nz_get_table_names to get the list of tables within a database.

Query across multiple databases on same server

I am looking for a way of dealing with the following situation:
We have a database server with multiple databases on it (all have the same schema, different data).
We are looking for a way to query across all the databases (and for it to be easy to configure, as more databases may be added at any time). This data access must be realtime.
Say, as an example, you have an application that inserts orders - each application has its own DB etc. What we are then looking for is an efficient way for a single application to then access the order information in all the other databases in order to query it and subsequently action it.
My searches to date have not revealed very much, however I think I may just be missing the appropriate keywords in order to find the correct info...
You must specify the database name before any database object.
Single database:
SELECT * FROM [dbo].[myTable]
Multiple dabases:
SELECT * FROM [DB01].[dbo].[myTable]
UNION ALL
SELECT * FROM [DB02].[dbo].[myTable]
UNION ALL
SELECT * FROM [DB03].[dbo].[myTable]
It's not going to be the cleanest solution ever, but you could define a view on a "Master database" (if your individual databases are not going to stay constant) that includes the data from the individual databases, and allows you to execute queries on a single source.
For example...
CREATE VIEW vCombinedRecords AS
SELECT * FROM DB1.dbo.MyTable
UNION ALL
SELECT * FROM DB2.dbo.MyTable
Which allows you to do...
SELECT * FROM vCombinedRecords WHERE....
When your databases change, you just update the view definition to include the new tables.
You can build the union dynamically:
select name from sys.databases
and then check if the database has the table:
select name from [dbname_from_above].sys.tables where name = 'YourTable'
That gives you all databases for the union. You can build the query client side or in dynamic SQL.
Note - My answer below received a couple down votes, but only one comment giving any reason why it might be down-voted. The comment was that this answer is very similar to the accepted answer, but even less performant. I disagree with this opinion and I reproduce my response here - in the actual answer - so that anyone else reading my answer might have a better chance at seeing why this is not the same as the accepted answer at all, and in fact better addresses the original question.
My response to the suggestion this is similar to the accepted answer:
on the contrary - the original question notes that new databases are added regularly. The accepted solution will require maintenance each time a new database is added. The solution here will work regardless of whether any new databases are added (in line with the original question that states they all have the same schema). Further, the accepted answer requires you to duplicate the query once per database queried. If the query is complex, that gets ugly fast. The proposal here ensures a single source of truth for the logic being used in the query.
And the answer itself:
Shooting from the hip here.
use master;
go
create table #Temp (sourceDBName varchar(128), colA varchar(128), colB varchar(128));
exec sp_MSforeachDB ' USE [?];
insert into #Temp
SELECT DISTINCT
''?'',
tableA.colA,
tableB.colB
FROM tableA JOIN tableB on some_conditions
WHERE someCol LIKE ''%some_term%''
'
select sourceDBName, colA, colB from #Temp order by 1, 2, 3;
drop table #Temp;
This logic should allow you to apply a single query to all databases. To use it though, you will want to add logic to filter out system databases, or explicitly include only the databases you specify. To achieve that, you might like to put this logic into a stored procedure which then returns a result set, so in the end, your call to this logic is a select statement that returns a rowset you can join, filter, etc.
Check out https://www.mssqltips.com/sqlservertip/2855/sql-server-multi-database-query-with-registered-servers/
SELECT * FROM (
SELECT
##SERVERNAME as [ServerName],
##version [Version],
Format(##CONNECTIONS,'N0') [Conections],
Format(##CPU_BUSY ,'N0')[CPUBusy]
) SQLInfo
LEFT JOIN (
SELECT
##SERVERNAME AS [ServerName],
SERVERPROPERTY('ProductVersion') [Version Build],
SERVERPROPERTY ('Edition') AS [Edition],
SERVERPROPERTY('ProductLevel') AS [Service Pack],
CASE SERVERPROPERTY('IsIntegratedSecurityOnly')
WHEN 0 THEN 'SQL Server and Windows Authentication mode'
WHEN 1 THEN 'Windows Authentication mode'
END AS [Server Authentication],
CASE SERVERPROPERTY('IsClustered')
WHEN 0 THEN 'False'
WHEN 1 THEN 'True'
END AS [Is Clustered?],
SERVERPROPERTY('ComputerNamePhysicalNetBIOS') AS [Current Node Name],
SERVERPROPERTY('Collation') AS [ SQL Collation],
[cpu_count] AS [CPUs],
[physical_memory_kb]*0.00000095367432 AS [RAM (GB)]
FROM [sys].[dm_os_sys_info]
) SQLInfo2 on SQLInfo.[ServerName]=SQLInfo2.[ServerName]
LEFT JOIN (
SELECT
##SERVERNAME as [ServerName],
NodeName,
Status_Description,
is_Current_Owner
FROM [MASTER].[sys].[fn_virtualservernodes]()
)Clusterinfo on SQLInfo.[ServerName]=Clusterinfo.[ServerName]

Query to count the exact number of records in all tables

IHello,
I'm trying to count for each table in my MySQL database how many records there are in it.
All of my tables happen to be in InnoDB and this query
SELECT TABLE_ROWS FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = 'myschema';
is way much too much of an estimate (There are +846 records and it tells me there are only +-400)
Is there a way to count a more exact number of rows with a similar query? It doen't matter how long the query takes tot run. (P.S. not using php or a similar language)
If the length of the query doesn't matter then what about doing the following for each table in your database:
select Count(*) from MyTable
If your are going to use the system views then you need to make sure your database statiscs are updated or the counts of rows will potentially be incorrect in the system schema views such as information_schema.x.
Use the
select count(*) yourtable;
as stated in the answer above to get the exact number
Analyze table yourtable;
to update the statisitcs then check the count in the system view they should match at ths point for number of rows.
see this website for more details and a way to do this for your entire database:
MySQL reference manual
As posted in this Answer
create table #rowcount (tablename varchar(128), rowcnt int)
exec sp_MSforeachtable
'insert into #rowcount select ''?'', count(*) from ?'
select * from #rowcount
order by tablename
drop table #rowcount