我正在使用 sqlcmd 将表导出到 TSV 文件,但遇到了问题。该表有 16 多万行和大约 55 列。
问题是它没有导出完整的表,但似乎在各个点随机停止(我猜是超时?)每次导出不同数量的行并且每次文件的大小略有不同(表明我没有达到任何行或大小限制)。
我没有使用任何超时开关(意味着使用“只要需要”的默认值)。
这是我的命令(为了简化和说明目的,删除了大多数列):
sqlcmd -U myUsername -P myPassword -S SERVERNAME -d "DBNAME" -Q "SELECT ROW_KEY, ISNULL(CARRIER_ID, ''),ISNULL(CONVERT(VARCHAR(19),ORDER_DATETIME,120),''),ISNULL(HEIGHT, ''),ISNULL(RESIDENTIAL_CHARGE, '') FROM MYTABLE" -o "OUTPUT_FILE.txt" -h-1 -s"|" -W
Run Code Online (Sandbox Code Playgroud)
我想知道它是否与超时或在所有列上使用 ISNULL() 有关(尽管当我在 sql server management studio 中运行查询时,我得到了正确的行数,例如 1600 万+)?
同样,我每次得到大约 4-8 百万行,但从来没有得到全部。我在 sql server 2k5 db 中,并从带有 sql server 2k8 的远程机器运行 sqlcmd。
我正在尝试在 sqlcmd 模式下为表列表执行 sql 过程,以将所有输出重定向到每个表的一个文件中。
不幸的是,只有所有命令的重定向输出的最后一个文件才能获得内容。
例如,我执行以下操作:
:OUT c:\test\tab0.sql
EXEC [dbo].[sp_generate_merge] @schema = 'dbo', @table_name ='tab0', @include_timestamp = 0, @ommit_images = 1, @CreateProcedure = 1
:OUT c:\test\tab1.sql
EXEC [dbo].[sp_generate_merge] @schema = 'dbo', @table_name ='tab1' , @include_timestamp = 0, @ommit_images = 1, @CreateProcedure = 1
Run Code Online (Sandbox Code Playgroud)
两个文件都被创建,但只有最后一个文件获得所有内容。
任何提示我可以如何更改它以便在每个命令的一个文件中获得结果?
我创建了一个以 XML 格式输出数据的脚本,并使用 SQL Server 代理(“操作系统 (cmdexec)”类型的作业步骤)每月/每季度运行一项作业,以将数据输出到特定文件。然而,我们遇到的问题是 SQLCMD 脚本的输出:
sqlcmd -d <Database> -i "<Package>\<SQLFile>.sql" -o "<OutputFilePath>\<FileName>.xml" -y 0
正在输出“消息”和“结果”。有没有办法只通过sqlcmd写入结果?
我删除了一些消息,包括:
“警告:空值会被聚合或其他 SET 操作消除。”
“(受影响的 1 行)”
通过使用以下代码:
SET NOCOUNT ON
SET ANSI_WARNINGS OFF
GO
Run Code Online (Sandbox Code Playgroud)
感谢您的建议!
我在一个 SQL 文件中有一个还原数据库脚本,我正在尝试将从一个数据库生成的备份还原到一个新的数据库(存在)。SQLCMD 正在命令行上执行该 SQL 文件。命令窗口让我知道恢复成功完成;但是数据库还处于恢复状态,无法访问。因此,我的批处理过程的其余部分失败。如何让数据库退出恢复状态并返回到联机状态,以便我可以运行其他批处理脚本?
我正在使用它来做到这一点:
restore filelistonly
from disk = 'c:\program files\microsoft sql server\mssql10.mssqlserver\mssql\backup\olddb.bak'
GO
RESTORE DATABASE NewDB
FROM DISK = 'C:\Program Files\Microsoft SQL Server\MSSQL10.MSSQLSERVER\MSSQL\Backup\olddb.bak'
WITH NORECOVERY, REPLACE,
MOVE 'OldDB' TO 'C:\Program Files\Microsoft SQL Server\MSSQL10.MSSQLSERVER\MSSQL\DATA\newdb.mdf',
MOVE 'OldDB_Log' TO 'C:\Program Files\Microsoft SQL Server\MSSQL10.MSSQLSERVER\MSSQL\DATA\newdb.ldf'
Run Code Online (Sandbox Code Playgroud)
如果我的数据库说它成功完成,为什么我的数据库仍然处于恢复状态,有什么想法吗?
谢谢。
假设使用 Microsoft SQL Management Studio 创建了如下存储过程。
use testbase
go
create procedure testtable_pricesmaller
@pricelimit money
as
select * from testtable where price = @pricelimit;
go
Run Code Online (Sandbox Code Playgroud)
是否可以修改使用SQLCMDMS SQL 的存储过程?
我现在正在使用sqlcmd一段时间来更新我们项目的数据库。
在我们使用这样的脚本之前:
:setvar relativepath D:\Project1\Sql
:r $(relativepath)\Tables\CreateTable1.sql
:r $(relativepath)\SP\Table1.sql
Run Code Online (Sandbox Code Playgroud)
这是在开发和发布期间更新数据库的好方法。
但是现在我们使用不同的目录,这取决于我们是在开发分支还是生产分支(Subversion)。
我们希望避免错误,以防有人通过根据所选数据库名称设置路径将脚本提交到错误的目录。像这样的事情:
:setvar relativepath "D:\Project1\Prod\Sql"
if (DB_name() = 'Project1' OR DB_name() = 'Project1_Dev')
begin
:setvar relativepath "D:\Project1\Dev\Sql"
end
Run Code Online (Sandbox Code Playgroud)
我找不到办法做到这一点。有人有想法吗?
[更新] 解决方案:(坦克到 wBob)
我有一个名为的脚本: setRelativePath.sql
:out D:\Project1\SQL\Temp\temp.sql
go
declare @bdName varchar(15) = DB_name()
--Here the print got saved to D:\Project1\SQL\Temp\temp.sql
if @bdName = 'Project1' OR @bdName = 'Project1_DEV'
print ':setvar relativepath D:\Project1\DEV\Sql'
else if @bdName = 'Project1_PROD'
print ':setvar relativepath D:\Project1\PROD\Sql'
else
raiserror( 'Unknown value (%s) for sqlcmd …Run Code Online (Sandbox Code Playgroud) 我参与了将旧的 AS400 系统转换为 SQL 服务器的项目。服务器用于我们的工资单处理。工资单流程的一部分是分解我们从事的每项工作的双周工资百分比。为此,在 AS400 流程中,将一个 csv 文件从 P&B 管理员加载到只有管理员有权访问的数据访问区域中的服务器。我需要在 SQL 服务器环境中复制它。我计划使用 SQLCMD 将本地文件导入到临时表中。我知道任何人都不太可能在使用临时表时查询临时表中的数据,但无论如何只授予执行 SQLCMD 脚本的用户的访问权限?
我的机器上安装了多个版本的 SSMS。我们有运行多个版本的 SQL Server 的旧服务器,主要是 2008、2012 和 2014。我一直使用 SQLCMD,但它似乎默认为该命令的 Version 10 版本。
C:\Program Files\Microsoft SQL Server\100\Tools\Binn
对于某些未启用向后兼容性的新服务器,我需要使用较新版本中的那个。
C:\Program Files\Microsoft SQL Server\110\Tools\Binn
我需要更改哪些设置,以便每次我想使用 SQLCMD 时都不必使用完整路径?
我正在尝试将一个批处理文件放在一起以运行大量 .sql 文件,而无需单独执行此操作。
到目前为止,我有:
@echo off
echo "Enter Server"
set /p SERVER=
echo "Enter Database"
set /p DATABASE=
del *.log
for /r %%i in (*.sql) do sqlcmd -E -S %SERVER% -d %DATABASE% -i"%%i" -m0 -o"%%i.log" -w500
pause
Run Code Online (Sandbox Code Playgroud)
就目前而言,这有效。
然而,我真正想做的是将任何错误路由到一个单独的 .err 文件,以便一目了然地清楚哪些(100+)个文件失败。
我看到了:Error参数,但我不确定如何在此处应用它。
有没有简单的方法来实现这一目标?
我的脚本包含多个GO关键字。我知道 SQLCMD 解释GO为批处理分隔符,因此代码不是作为单个块运行的,而是分隔符(批处理)之间的每个部分单独运行。我的问题是,所有批次都在同一个会话中执行吗?
我尝试使用一个简单的脚本来测试这个:
SELECT @@SPID
GO
SELECT @@SPID
GO
SELECT @@SPID
GO
Run Code Online (Sandbox Code Playgroud)
然后我使用此命令从命令行运行脚本
SELECT @@SPID
GO
SELECT @@SPID
GO
SELECT @@SPID
GO
Run Code Online (Sandbox Code Playgroud)
并得到这个输出:
SQLCMD -S MyServer\Instance -E -i MyScript.sql
Run Code Online (Sandbox Code Playgroud)
它似乎肯定地回答了我的问题,但后来我再次运行脚本并得到完全相同的输出,即所有值都是一样的62。显然,SQLCMD 的两个单独执行不可能在同一个会话中运行,它们只是碰巧收到了相同的会话 ID。但这反过来又让我认为@@SPID单次运行返回的相同值也不一定意味着它是同一个会话。每个批处理都可以在恰好收到相同 ID 的不同会话中执行,类似于 SQLCMD 的不同执行在具有相同 ID 的不同会话中运行的方式。
因此,我的问题仍然存在:是否在同一会话中在 SQLCMD 中执行了多个批次的相同脚本?有没有办法确定这一点?