31

我正在尝试使用 SQL 语句切换当前数据库。我尝试了以下方法,但所有尝试都失败了:

  1. 使用 @DatabaseName
  2. EXEC sp_sqlexec @Sql -- 其中@Sql = 'USE [' + @DatabaseName + ']'

添加更多细节。

编辑:我想在两个单独的数据库上执行几件事,其中两个都配置了一个变量。像这样的东西:

USE Database1
SELECT * FROM Table1

USE Database2
SELECT * FROM Table2
4

10 回答 10

13

前者的问题在于你所做的是USE 'myDB'而不是USE myDB. 你正在传递一个字符串;但 USE 正在寻找一个明确的参考。

后一个例子对我有用。

declare @sql varchar(20)
select @sql = 'USE myDb'
EXEC sp_sqlexec @Sql

-- also works
select @sql = 'USE [myDb]'
EXEC sp_sqlexec @Sql
于 2009-06-24T09:05:24.723 回答
12
   exec sp_execsql @Sql

数据库更改仅持续完成@sql 的时间

http://blog.sqlauthority.com/2007/07/02/sql-server-2005-comparison-sp_executesql-vs-executeexec/

于 2009-06-24T09:05:07.707 回答
11

我有同样的问题,我用一组丑陋但有用的 GOTO 克服了它。

我在一切之前称其为“脚本运行器”的原因是我想向任何只想使用实际脚本的开发人员隐藏复杂性和丑陋的方法。同时,我可以确保脚本以完全相同的方式在两个(可扩展到三个或更多)数据库中运行。

GOTO ScriptRunner

ScriptExecutes:

--------------------ACTUAL SCRIPT--------------------
-------- Will be executed in DB1 and in DB2 ---------
--TODO: Your script right here

------------------ACTUAL SCRIPT ENDS-----------------

GOTO ScriptReturns

ScriptRunner:
    USE DB1
    GOTO ScriptExecutes

ScriptReturns:
    IF (db_name() = 'DB1')
    BEGIN
        USE DB2
        GOTO ScriptExecutes
    END

使用这种方法,您可以保留您的变量,并且如果您碰巧两次检查 DECLARE 语句,SQL Server 也不会惊慌失措。

于 2012-11-08T17:18:10.037 回答
6

只是想感谢 KM 的宝贵解决方案。我自己实现了它以减少 SQLServer 上收缩数据库请求中的行数。如果它可以帮助任何人,这是我的 SQL 请求:

-- Declare the variable to be used
DECLARE @Query varchar (1000)
DECLARE @MyDBN varchar(11);
-- Initializing the @MyDBN variable (possible values : db1, db2, db3, ...)
SET @MyDBN = 'db1';
-- Creating the request to execute
SET @Query='use '+ @MyDBN +'; ALTER DATABASE '+ @MyDBN +' SET RECOVERY SIMPLE WITH NO_WAIT; DBCC SHRINKDATABASE ('+ @MyDBN +', 1, TRUNCATEONLY); ALTER DATABASE '+ @MyDBN +' SET RECOVERY FULL WITH NO_WAIT'
-- 
EXEC (@Query)
于 2016-07-27T08:52:57.947 回答
5

尝试这个:

DECLARE @Query         varchar(1000)
DECLARE @DatabaseName  varchar(500)

SET @DatabaseName='xyz'
SET @Query='SELECT * FROM Server.'+@DatabaseName+'.Owner.Table1'
EXEC (@Query)

SET @DatabaseName='abc'
SET @Query='SELECT * FROM Server.'+@DatabaseName+'.Owner.Table2'
EXEC (@Query)
于 2009-06-24T12:07:52.733 回答
2

我认为有人需要一个解决方案,这是一个:

如果您使用动态 USE 语句,则所有查询都必须是动态的,因为它需要是同一上下文中的所有内容。

您可以尝试使用 SYNONYM,基本上是特定表的别名,此 SYNONYM 被插入到 sys.synonyms 表中,因此您可以从任何上下文访问它

看看这个静态语句:

CREATE SYNONYM MASTER_SCHEMACOLUMNS FOR Master.INFORMATION_SCHEMA.COLUMNS
SELECT * FROM MASTER_SCHEMACOLUMNS

现在动态:

DECLARE @SQL VARCHAR(200)
DECLARE @CATALOG VARCHAR(200) = 'Master'

IF EXISTS(SELECT * FROM  sys.synonyms s WHERE s.name = 'CURRENT_SCHEMACOLUMNS')
BEGIN
DROP SYNONYM CURRENT_SCHEMACOLUMNS
END

SELECT @SQL = 'CREATE SYNONYM CURRENT_SCHEMACOLUMNS FOR '+ @CATALOG +'.INFORMATION_SCHEMA.COLUMNS';
EXEC sp_sqlexec @SQL

--Your not dynamic Code
SELECT * FROM CURRENT_SCHEMACOLUMNS

现在只需更改@CATALOG 的值,您将能够列出同一个表,但来自不同的目录。

于 2014-06-28T15:18:17.027 回答
1

如果 SQLCMD 是一个选项,它支持的脚本变量超出了直接 T-SQL 所能做的。例如:http: //msdn.microsoft.com/en-us/library/ms188714.aspx

于 2009-08-11T21:25:13.317 回答
0

你可以这样做:

Declare @dbName nvarchar(max);
SET @dbName = 'TESTDB';

Declare @SQL nvarchar(max);
select @SQL = 'USE ' + @dbName +'; {can put command(s) here}';
EXEC (@SQL);

{but not here!}

这意味着您可以执行如下递归选择:

Declare @dbName nvarchar(max);
SET @dbName = 'TESTDB';
Declare @SQL nvarchar(max);

SELECT @SQL = 'USE ' + @dbName + '; ' +(Select ... {query here}
For XML Path(''),Type)
.value('text()[1]','nvarchar(max)');

Exec (@SQL)
于 2016-08-22T12:50:07.473 回答
-1

利用exec sp_execsql @Sql

例子

DECLARE @sql as nvarchar(100)  
DECLARE @paraDOB datetime  
SET @paraDOB = '1/1/1981'  
SET @sql=N'SELECT * FROM EmpMast WHERE DOB >= @paraDOB'  
exec sp_executesql @sql,N'@paraDOB datetime',@paraDOB
于 2009-06-24T09:16:26.043 回答
-2
-- If you are using a variable for the database name. 
-- Try something like this. 

DECLARE @DBName varchar(50)
Set @DBName = 'Database1'; /*  could be passed in by a parameter. */

IF( @DBName = 'Database1')
Begin
    USE [Database1];
SELECT  FROM Table1;
End

IF( @DBName = 'Database2')
Begin
USE [Database2];
SELECT  FROM Table2;
End

IF( @DBName is null)
Begin
USE [Database1];
End
于 2009-08-11T18:16:05.930 回答