无法使用系统在SQL Server中创建多个用户定义函数.数据SqlClient



我正试图从同一.sql文件中创建多个用户定义的函数。我正在使用SQL Server,并使用C#的System.Data中的SqlClient执行查询。

.sql文件的内容:

CREATE FUNCTION [dbo].[GetUserId] (@username VARCHAR(32))
RETURNS INT
AS
BEGIN
DECLARE @userId INT = -1
SET @userId = (SELECT DISTINCT UserId FROM Users WHERE UserName = @username)
RETURN @userId
END
GO
CREATE FUNCTION [dbo].[GetUserId2] (@username2 VARCHAR(32))
RETURNS INT
AS
BEGIN
DECLARE @userId2 INT = -1
SET @userId2 = (SELECT DISTINCT UserId FROM Users WHERE UserName = @username2)
RETURN @userId2
END

以下是我执行语句时抛出的错误:

系统。数据SqlClient。SqlException:"GO附近的语法不正确。">
必须声明标量变量"@username2">
"END"附近的语法不正确

有什么想法吗?一般来说,我是SQL的新手,但这对我来说似乎缺乏对语法/批处理的理解

编辑:我注意到"GO"是SQL Server Management Studio的一部分,而不是SqlClient。如果我从.sql文件中删除"GO",那么我会得到以下错误:

"REATE FUNCTION"必须是查询批处理中的第一条语句。

如何在不使用"GO"的情况下分离CREATE FUNCTION语句?

不能在一条语句中运行多个批处理。

我建议您使用GO拆分TSQL语句,然后逐个执行批处理。

string multipleUDFs = "CREATE FUNCTION... " +
"GO" + 
"CREATE FUNCTION ";
List<string> statementsToExecute = multileUDFs.Split("GO").ToList();
// Create the command 
var command = new SqlCommand(myConnection);
foreach(string sqlcommand in statementsToExecute)
{
// Change the SQL Command and execute
command.CommandText = sqlcommand;
command.ExecuteNonQuery();
}

下面是一个使用服务器管理对象(SMO(API和最新预览NuGet包的示例。与SqlClient不同,SMO可以使用GO批处理终结符运行脚本,类似于SSMS和SQLCMD。

using System.IO;
using System.Data.SqlClient;
//reference latest NuGet preview package https://www.nuget.org/packages/Microsoft.SqlServer.SqlManagementObjects/160.1911221.0-preview#
using Microsoft.SqlServer.Management.Common;
namespace ConsoleApp1
{
class Program
{
static void Main(string[] args)
{
using (var connection = new SqlConnection("Data Source=.;Integrated Security=SSPI"))
{
var serverConnection = new ServerConnection(connection);
connection.Open();
var sqlScript = File.ReadAllText(@"C:tempScriptWithGoBatchTerminators.sql");
serverConnection.ExecuteNonQuery(sqlScript);
}
}
}
}

除了Dan Guzman使用SMO给出的答案外,您还可以将SQL脚本文本拆分为单独的SQL批,并在同一连接上依次执行每个批。这就是SSMS和SMO所做的一切:

/// <summary>
/// Executes a script-like SQL string, using GOs to break it into
/// seperate batches within the same session
/// </summary>
public void ExecSqlScript(string sqlScript, SqlConnection conn)
{
// change all line-breaks to LF
string script = sqlScript.Replace("rn", "n").Replace("r", "n");
// split the script into separate batches using "GO"
string[] batches = script.Split(new[] { "nGOn", "ngOn", "nGon", "ngon" }, StringSplitOptions.RemoveEmptyEntries);
// execute each batch on the same connection/session
foreach(string batch in batches)
{
SqlCommand cmd = new SqlCommand(batch, conn);
cmd.ExecuteNonQuery();
}
}

注意:未测试

最新更新