Невозможно создать несколько пользовательских функций на сервере SQL с использованием System.Data.SqlClient - PullRequest
0 голосов
/ 23 марта 2020

Я пытаюсь создать несколько пользовательских функций из одного файла. sql. Я использую SQL Server и выполняю свои запросы, используя SqlClient из C# s System.Data.

Содержимое файла. 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

Вот ошибка, которая выдается, когда я выполняю инструкцию:

System.Data.SqlClient.SqlException: 'Неверный синтаксис рядом с' GO '.
Должен объявить скалярную переменную "@ username2 ".
Неверный синтаксис рядом с 'END'. '

Есть идеи? Я новичок в SQL в целом, но мне кажется, что мне не хватает понимания синтаксиса / пакетирования.

РЕДАКТИРОВАТЬ: Мне стало известно, что GO является частью SQL Server Management Studio, а не SqlClient. Если я удаляю 'GO' из моего файла. sql, я получаю эту ошибку:

'CREATE FUNCTION' должен быть первым оператором в пакете запроса.

Как разделить операторы CREATE FUNCTION без использования GO?

Ответы [ 3 ]

2 голосов
/ 23 марта 2020

Ниже приведен пример использования API управления объектами сервера (SMO) с последним предварительным просмотром пакета 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:\temp\ScriptWithGoBatchTerminators.sql");
                serverConnection.ExecuteNonQuery(sqlScript);
            }
        }
    }
}
2 голосов
/ 23 марта 2020

Вы не можете запустить несколько пакетов в одном операторе.

Я бы предложил разделить ваш оператор T SQL, используя GO, а затем выполнить пакеты по одному.

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();
}
0 голосов
/ 23 марта 2020

В дополнение к ответу Дэна Гузмана с использованием 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("\r\n", "\n").Replace("\r", "\n");

        // split the script into separate batches using "GO"
        string[] batches = script.Split(new[] { "\nGO\n", "\ngO\n", "\nGo\n", "\ngo\n" }, StringSplitOptions.RemoveEmptyEntries);

        // execute each batch on the same connection/session
        foreach(string batch in batches)
        {
            SqlCommand cmd = new SqlCommand(batch, conn);
            cmd.ExecuteNonQuery();
        }
    }

Примечание: не проверено

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...