I'm trying to make a simple select query on several databases on the same server, the server has 104 databases where 52 have the same schema so that is 2 different schemas (this are being generated by equipment on production floor, is a mistake that I have to handle until the equipment vendor figures how to create a single database for each scheme).
So I have a query like
select *
from TB_AOIResult
where serialnumber = 'snx'
At first I use this, it retrieves the data, but also a lot of errors as several databases on the server do not have that table .
[exec sp_MSforeachdb 'use ?;SELECT * FROM \[TB_AOIResult\] where barcode ="102564AG1710200018476"'
go]1
then
so far the only way that I have found is to declare all the 52 databases (at this moment, the machines will generate a new db per week) in this statement, that is severally impractical
declare #sql1 as VARCHAR(4000)
SET #sql1 ='IF ''?''IN(''KY_Result_201715'',''KY_Result_201714'',''KY_Result_201713'',''KY_Result_201712''[enter image description here][2])
EXECUTE(''USE [?]
SELECT * FROM [TB_AOIResult] where barcode ="102564AG1710200018476" '')'
EXEC sp_MSforeachdb #command1 = #sql1
Could someone help me and explain me if there is any other way to do this query in all the databases with the same schema and avoid to run in the ones that does not have the table, without write the name of each database?
Thanks
Finally I solve it as follows:
exec sp_MSforeachdb #command1 = 'USE ?;
IF EXISTS (SELECT * FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = N''TB_AOIResult'') BEGIN SELECT * FROM TB_AOIResult where barcode like ''102564AG171020001847%'' END'
go
Related
Observe the following simple SQL code:
CREATE TABLE #tmp (...) -- Here comes the schema
INSERT INTO #tmp
EXEC(#Sql) -- The #Sql is a dynamic query generating result with a known schema
All is good, because we know the schema of the result produced by #Sql.
But what if the schema is unknown? In this case I use Powershell to generate a Sql query like that:
SET #Sql = '
SELECT *
INTO ##MySpecialAndUniquelyNamedGlobalTempTable
FROM ($Query) x
'
EXEC(#Sql)
(I omit some details, but the "spirit" of the code is preserved)
And it works fine, except that there is a severe limitation to what $Query can be - it must be a single SELECT statement.
This is not very good for me, I would like to be able to run any Sql script like that. The problem, is that no longer can I concatenate it to FROM (, it must be executed by EXEC or sp_executesql. But then I have no idea how to collect the results into a table, because I have no idea of the schema of that table.
Is it possible in Sql Server 2012?
Motivation: We have many QA databases across different Sql servers and more often than not I find myself running queries on all of them in order to locate the database most likely to yield best results for my tests. Alas, I am only able to run single SELECT statements, which is inconvenient.
We use SP and OPENROWSET for this purpose.
At first create SP based on a query you need, than use OPENROWSET to get data into temp table:
USE Test
DECLARE #sql nvarchar(max),
#query nvarchar(max)
SET #sql = N'Some query'
IF OBJECT_ID(N'SomeSPname') IS NOT NULL DROP PROCEDURE SomeSPname
SET #query =N'
CREATE PROCEDURE SomeSPname
AS
BEGIN
'+#sql+'
END'
EXEC sp_executesql #query
USE tempdb
IF OBJECT_ID(N'#temp') IS NOT NULL DROP TABLE #temp
SELECT *
INTO #temp
FROM OPENROWSET(
'SQLNCLI',
'Server=SERVER\INSTANCE;Database=Test;Trusted_Connection=yes;',
'EXEC dbo.SomeSPname')
SELECT *
FROM #temp
I often run into MSSQL databases that have many more tables than are listed in information_schema or systables.
For example, I'm querying a database right now but only getting the tables spt_fallback_db, spt_fallback_dev, spt_fallback_usg, spt_monitor, spt_values. (1)
How does this happen?
And - can it be fixed easily?
(1) I should clarify that this isn't a permissions issue, as I am sysadmin on the database ; there are around 200 tables and I have full permission on all of them.
#DeadZone was right on the money, the query had some issues.
I was using:
DECLARE #command varchar(1000)
SELECT #command = 'SELECT * FROM sysobjects WHERE xtype=''U'' '
EXEC sp_MSforeachdb #command
But it would only show system tables. So then I switched to a more direct query to see what was going on and was able to view the tables:
use MYDATABASENAME;
SELECT * FROM sysobjects WHERE xtype='U'
I have a SQL 2008 database that is stored on the same instance, but this database is created by the user and name is stored in SQL table. How do I write a select statement using dynamic sql or is there a another way
So for example:
Main database - myDB
User database - userDB (this is stored in a myDB.dbo.tblUserDatabase)
userDB has a table called tblUserReports
I want to write something like this in dynamic sql:
SELECT * FROM userDB.dbo.tblUserReports
So tried:
declare #dbUser varchar(50)
set #dbUser = (SELECT strDBName FROM myDB.dbo.tblUserDatabase)
SELECT * FROM #dbUser.dbo.tblUserReports
You can do this... dynamic sql can become unmanageable very quickly so be careful.
declare #dbUser varchar(50)
set #dbUser = (SELECT strDBName FROM myDB.dbo.tblUserDatabase)
DECLARE #sql NVARCHAR(1000)
SET #sql = 'SELECT * FROM ' + QUOTENAME(#dbUser) + '.dbo.tblUserReports'
EXEC sp_executesql #sql
You cannot parameterise the table name. You will have to use dynamic SQL in your client or stored procedures. It's a very unusual thing to want to do so think long & hard about if this is a good design. Maybe if you share what you are doing then you'll get some additional ideas as to how to approach your problem.
I would like to split my database into two databases, a quick check showed that I can easily query, join, update tables across databases.
My main problem now is that to do this, I will have to do something like this.
SELECT *
FROM Database1.dbo.Table1,
Database2.dbo.Table2
As you can see I have to explicit mentioned database names, which means that if database name is deployed with a different name, this code will not work anymore.
Any ideas to overcome this problem?
You can use db_name() to get the current database name and dynamic sql to build a dynamic query.
Something like:
declare #databaseName nvarchar(max) = db_name()
declare #dynamicSql nvarchar(max) = 'SELECT * FROM '+ #databaseName + '.dbo.Table1'
exec sp_executesql #dynamicSql
I restored a database after a server failure and now I'm running into a problem where the table names show as database_user_name.table_name. So when I query something like:
select * from contacts
it doesn't work because it expects it be fully qualified, as in:
select * from user1000.contacts
The problem with this is that I have hundreds of stored procedures that reference the tables with their name, so none of the queries work.
Is there a way to tell SQL Server 2005 to drop the username from the table without changing the user as the owner?
try this advice from the manual:
To change the schema of a table or view by using SQL Server Management Studio, in Object Explorer, right-click the table or view and then click Design. Press F4 to open the Properties window. In the Schema box, select a new schema.
If you are sure none of the tables exist in the dbo schema as well, then you can say:
ALTER SCHEMA dbo TRANSFER user1000.contacts;
To generate a set of scripts for all of the tables in that schema, you can say:
DECLARE #sql NVARCHAR(MAX);
SET #sql = N'';
SELECT #sql = #sql + N'
ALTER SCHEMA dbo TRANSFER user1000.' + QUOTENAME(name) + ';'
FROM sys.tables
WHERE SCHEMA_NAME([schema_id]) = N'user1000';
PRINT #sql;
--EXEC sp_executesql #sql;
(Once you're happy with the PRINT output - acknowledging that it will be truncated at 8K even though the variable really contains the whole script - uncomment the EXEC and run it again. This does not check for potential conflicts.)
But the real fix is to fix your code. You should never say select * from contacts - both the * and the missing schema prefix can be problematic for various reasons.