我试图获取包含两个具有特定名称的独立表格的所有数据库的列表(在这种情况下,' MasterSchedules','用户')。
我尝试的第一件事是用光标做到这一点:
DECLARE dbCursor CURSOR FOR
SELECT name
FROM sys.databases
WHERE name NOT IN ('master', 'tempdb', 'model', 'msdb')
DECLARE @dbname varchar(max)
OPEN dbCursor
FETCH NEXT FROM dbCursor INTO @dbname
WHILE @@FETCH_STATUS = 0
BEGIN
DECLARE @stmt nvarchar(max)
SET @stmt = 'USE ' + @dbname + ';';
EXECUTE sp_executesql @stmt
SELECT TABLE_CATALOG, TABLE_NAME
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_TYPE = 'BASE TABLE'
AND TABLE_NAME in ('MasterSchedules', 'Users')
ORDER BY TABLE_SCHEMA + '.' + TABLE_NAME
FETCH NEXT FROM dbCursor INTO @dbname
END
CLOSE dbCursor;
DEALLOCATE dbCursor;
然而,所有这一切都是反复获取相同的数据。
---------------------------------------
| | TABLE_CATALOG | TABLE_NAME |
|--------------------------------------
| 1 | QA_CTLG | MasterSchedules |
---------------------------------------
---------------------------------------
| | TABLE_CATALOG | TABLE_NAME |
|--------------------------------------
| 1 | QA_CTLG | MasterSchedules |
---------------------------------------
---------------------------------------
| | TABLE_CATALOG | TABLE_NAME |
|--------------------------------------
| 1 | QA_CTLG | MasterSchedules |
---------------------------------------
...
我已将其缩小到EXECUTE sp_executesql...
显然没有效果的事实。有谁知道为什么会这样或如何解决它?
对于记录,是的,我确实知道这将显示至少有一个表的数据库,而不是那两个表的数据库。
我想过尝试使用某种动态SQL,但我想到的并不是仅仅使用光标。
我还尝试编写一个查询来执行此操作(如下所示):
select
name
from
sys.databases
where
name not in ('master', 'tempdb', 'model', 'msdb')
and exists (select top 1 TABLE_NAME
from [name].INFORMATION_SCHEMA.TABLES
where TABLE_NAME = 'Users')
and exists (select top 1 TABLE_NAME
from [name].INFORMATION_SCHEMA.TABLES
where TABLE_NAME = 'MasterSchedules')
不出所料,这会返回错误
无效的对象名称' @ name.INFORMATION_SCHEMA.TABLES'
我可以使用name
代替ref.addListenerForSingleValueEvent(new com.google.firebase.database.ValueEventListener() {
@Override
public void onDataChange(com.google.firebase.database.DataSnapshot dataSnapshot) {
rface = dataSnapshot.child("face").getValue(String.class);
}
@Override
public void onCancelled(DatabaseError databaseError) {
}
});
来实现此功能(或修复光标的方法)吗?
答案 0 :(得分:4)
这是使用动态sql执行此操作的一种非常简单的方法。这将返回具有这两个表名的所有数据库。它不需要循环,游标或临时表。
<a href="#">test</a>
- EDIT-- 您可能希望将架构添加到此查询中。它将作为默认模式中的表的发布工作,但如果具有任一名称的表存在于多个模式中,则这将不会像宣传的那样工作。
答案 1 :(得分:1)
尝试使用这个轻微修改过的代码版本...使用动态SQL而不是脚本化“USE”语句,修复你的ORDER BY以使用逗号而不是点...这似乎对我有用,具体取决于您希望输出的内容:
DECLARE @dbname sysname;
DECLARE dbCursor CURSOR FOR
SELECT name FROM sys.databases WHERE name not in ('master', 'tempdb', 'model', 'msdb');
OPEN dbCursor;
FETCH NEXT FROM dbCursor INTO @dbname;
WHILE @@FETCH_STATUS = 0
BEGIN
DECLARE @stmt nvarchar(max)
SELECT @stmt = N'SELECT TABLE_CATALOG, TABLE_NAME FROM ' + @dbname + N'.INFORMATION_SCHEMA.TABLES ' +
N'WHERE TABLE_TYPE = ''BASE TABLE'' AND TABLE_NAME in (''MasterSchedules'', ''Users'') ' +
N'ORDER BY TABLE_SCHEMA, TABLE_NAME';
EXEC(@stmt);
FETCH NEXT FROM dbCursor INTO @dbname
END
CLOSE dbCursor;
DEALLOCATE dbCursor;
答案 2 :(得分:0)
您将不得不在此处使用动态sql并遍历每个数据库,而无需知道每个数据库的名称。假设您具有查询服务器上所有数据库的正确访问权限:
use master
declare @cursor table (dbname varchar(150))
declare @dbname varchar(150)=''
declare @sql nvarchar(500)=''
if object_id('tempdb..#results') is not null drop table #results
create table #results (dbname varchar(150), tblname varchar(150))
set nocount on
insert into @cursor
select name
from sys.sysdatabases db
where name not in ('master', 'tempdb', 'model', 'msdb')
select @dbname = min(dbname) from @cursor -- first row
While @dbname Is Not Null
Begin
set @sql = ('
insert into #results (dbname, tblname)
select ' + char(39) + @dbname + char(39) + ' , name from ' + @dbname + '.sys.tables where name in (''MasterSchedules'', ''Users'')
')
exec sp_executesql @sql
select @dbname = min(dbname) from @cursor where dbname > @dbname -- next row
End
select * from #results