【问题标题】:Is it possible to get the content of a script file in a database project?是否可以在数据库项目中获取脚本文件的内容?
【发布时间】:2019-09-29 18:21:29
【问题描述】:

好的,所以我有一个 Visual Studio 数据库项目,我正在尝试做一些 部署后的工作 (Script.PostDeployment.sql)。

我想做什么?

我喜欢做的是能够复制脚本文件的内容并将其插入到程序中

概述

所以我有一个带有一些 SQLCMD 的文件

MyScriptFileWithSomeInserts.sql -- The content I like to log is in this file

exec InsertDataProcedure [ScriptContent] -- How can I get it here?

这里有一些我正在尝试做的伪代码

-- read file and insert to variable
:setvar ScriptContent :r MyScriptFileWithSomeInserts.sql 

-- input the content to the procedure
exec InsertDataProcedure [@ScriptContent] 

我尝试了什么?

1

以下失败,因为这不是一个过程,而只是我的数据库项目中的一个脚本。

declare @ScriptContent nvarchar(Max)
SELECT @ScriptContent = OBJECT_DEFINITION(OBJECT_ID(N'MyScriptFileWithSomeInserts.sql'))
exec InsertDataProcedure @ScriptContent 

2

我尝试使用 :r (SQLCMD) 来读取文件

declare @xx nvarchar(Max) =
:r MyScriptFileWithSomeInserts.sql

exec InsertDataProcedure [@ScriptContent] 

3

我尝试使用SQLCMD 的各种变体,例如 :i 来读取文件

declare @xx nvarchar(Max) =
:i MyScriptFileWithSomeInserts.sql

exec InsertDataProcedure [@ScriptContent] 

我的设置

Visual Studio 2019 和目标平台 MS Azure SQL 数据库 V12。

更新:这是如何解决的

这是我在约翰的帮助下得到的结果。

DECLARE @solutionDir VARCHAR(200),@File VARCHAR(200)
-- In the SQLCMD I have access to $(SolutionPath) so I need to do some 
-- cleaningto get the absolute path to the file
SELECT @solutionDir = REPLACE('$(SolutionPath)','MySolution.sln','');
SET @File = @solutionDir + 'Databases\MyDb\MyScriptFileWithSomeInserts.sql'
        
DECLARE @retvalue nvarchar(max)  
DECLARE @SQL nvarchar(max);
DECLARE @ParmDef nvarchar(50);

-- Read the content of the file
SELECT @SQL = N'SELECT @retvalOUT = BulkColumn FROM OPENROWSET(BULK ''' + @File + ''', SINGLE_BLOB) AS x' ;   
SET @ParmDef = N'@retvalOUT nvarchar(max) OUTPUT';
 
EXEC sp_executesql @SQL, @ParmDef, @retvalOUT=@retvalue OUTPUT;

-- And here I have all the content of the file.
PRINT '@retvalue: ' + @retvalue

【问题讨论】:

  • sp_executesql。并且不要将 SQLCMD 变量与 TSQL 变量混淆。不是一回事。
  • 我忘了注意我确实尝试使用 sp_executesql 但没有成功。你能告诉我你的想法吗?
  • 我只有一秒钟的时间来浏览它。因此,如果您能够从 SQLCMD 运行,那么为什么不只是 :r MyScriptFileWithSomeInserts.sql 后跟 GO
  • 查看我使用 :r 的尝试 nr 2。我试图将文件的所有内容发送到我将其保存到表的过程中。这是一个审计举措。因此,我一直在尝试以各种可以想到的方式使用 :r(至少对我而言)。请告诉我,如果你有这个给我,那就太棒了!
  • 好吧,如果您需要将其作为字符串引入并将其传递给存储过程以进行审计,从而改变事情。您是否可以控制如何创建此插入批次?多长时间?

标签: sql sql-server sqlcmd database-project


【解决方案1】:

只是一个想法,但我没有在您的列表中看到 OPENROWSET

Declare @S varchar(max); 
Select @S = BulkColumn FROM  OPENROWSET(BULK 'C:\SomeDir\SomeScript.sql', SINGLE_BLOB) x; 


Print @S
--Exec(@S)

【讨论】:

  • 明天去试试这个(晚上在这里 atm)!
  • 好的,如果我把绝对路径放到文件中,这可以工作。现在我只需要找出与项目相比如何获得文件的相对路径。我不想硬编码'C:\Dev\ProjectName\DatabaseProject\Data\Inserts\SomeScript.sql'。知道怎么做吗? $(SolutionDir) 会很棒,但这似乎不起作用。
  • @Sturla 您必须将整个内容包装在动态 SQL 中。这意味着您将在动态 SQL 中拥有动态 SQL。在我看来有点乱。我会多加一点。
  • 嗨@John 我拼凑了你答案的动态版本,但我有一些我没有发现的语法错误。你能帮我看看吗?然后我会给你正确的答案,因为你让我走上了正确的道路(90%)。
  • @Sturla 您将 (at)SQL 设置为 nvarchar(50) 而不是 nvarchar(max) 它正在被截断。
【解决方案2】:

转到数据库,然后右键单击您想要脚本的表并单击“脚本表为”,它会显示另一个显示“创建到”的部分,单击它并打开另一个部分,然后选择“新查询编辑器窗口" 点击它,你的查询就会显示出来,复制它并粘贴到需要的地方。 右键单击表---->脚本表作为---->创建到---->新的查询编辑器窗口 其实我没有得到你的解释正确。我只是向你展示了如何让脚本从一个地方复制到另一个地方

【讨论】:

  • 谢谢,但这是一个 Visual Studio 数据库项目,我有条件(使用 SQLCMD)运行脚本。它们是 *.sql 文件,但在我的情况下仅包含插入/更新/删除数据。但我想通过(以某种方式)读取脚本文件并将内容发送到日志记录过程中,将这些操作记录到数据库中。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-10-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多