SQL Server: не удается найти тип данных - ошибка возникает только внутри более крупного скрипта - PullRequest
0 голосов
/ 22 октября 2018

Я создаю UDF.
Функция успешно создана ТОЛЬКО , если я сам запускаю блок CREATE FUNCTION.

Если я включаю блок CREATE FUNCTION внутригораздо больший "полный" сценарий создания БД, я получаю странное сообщение об ошибке, в котором говорится, что использовался неверный тип данных.
(см. блок кода и снимок экрана ниже.)

USE MyDB, SET ANSI_NULLSи SET QUOTED_IDENTIFIER идентичны в обоих случаях и не имеют никакого эффекта.

Это очень странно, поскольку UDTT создается намного раньше в сценарии создания БД без ошибок.Я вижу UDTT в SSMS, так что он явно существует ...

Если я перезапущу полный сценарий создания БД, я, очевидно, получаю кучу сообщений о воссоздании объектов, которые уже существуют - я игнорирую эти сообщенияпотому что это ожидаемо.
Но затем я получаю эту ошибку, которая приводит к сбою создания этой конкретной функции, которая блокирует многие другие создания объектов после нее.

Если я удаляю базу данных и повторно запускаюзавершен сценарий создания базы данных, я не получаю ошибок до этой строки и все еще получаю то же сообщение об ошибке, что этот тип данных недействителен.

Что может быть причиной этого?
Если я хотел «починить»полный сценарий создания БД, с чего мне начать?

USE MyDB
GO

SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO

CREATE FUNCTION [dbo].[Test_FloatToNString] ( )

RETURNS @TestResults TABLE (
                               [Category]      NVARCHAR ( MAX ) NOT NULL ,
                               [Example]       NVARCHAR ( MAX ) NOT NULL ,
                               [Expected]      NVARCHAR ( MAX ) NOT NULL ,
                               [Actual]        NVARCHAR ( MAX ) NOT NULL ,
                               [CaseSensitive] BIT              NOT NULL ,
                               [Tolerance]     NVARCHAR ( MAX ) NOT NULL ,
                               [Difference]    NVARCHAR ( MAX ) NOT NULL ,
                               [Passed]        BIT              NOT NULL ,
                               [Description]   NVARCHAR ( MAX ) NOT NULL
                           )
AS BEGIN

    DECLARE @testData [NStringTestData] ;   /* Error here, see screenshot below */

    INSERT INTO @testData   /* etc. */

enter image description here

Вот как выглядит UDTT в полном сценарии создания БД:

USE MyDB
GO

/* ... */

CREATE TYPE [dbo].[NStringTestData] AS TABLE(
    [Category] [nvarchar](max) NOT NULL,
    [Example] [nvarchar](max) NOT NULL,
    [Expected] [nvarchar](max) NOT NULL,
    [Actual] [nvarchar](max) NOT NULL,
    [CaseSensitive] [bit] NOT NULL,
    [Tolerance] [int] NOT NULL,
    [Description] [nvarchar](max) NOT NULL
)
GO

Ответы [ 2 ]

0 голосов
/ 22 октября 2018

Метод отладки, опубликованный user5151179, очень полезен.
Вот посмертное вскрытие, которое может помочь другим сузить проблему в подобных ситуациях.

Эта проблема вызвана сценарием БД, содержащим изначальноскомпилированные функции / процедуры, создаваемые до проблемной функции (которая не изначально скомпилирована и не ссылается на какие-либо модули с естественным соблюдением).

Я до сих пор понятия не имею почему это происходит, но перемещение нескольких десятков встроенных функций в другое «место» в скрипте (ближе к низу и, самое главное, после создания проблемной функции) полностью решило проблему, не изменяяЛюбая из функций или процедур.

Каждый объект в базе данных точно такой же, как и прежде, просто создан в другом порядке.

Это сбивает с толку меня, потому что не было никаких ссылок междулюбой из этих объектов, который потребовал бы, чтобы они были созданы в spчеткий порядок - и сама ошибка была просто ошибкой типа данных для UDTT, который был в самом верху моего сценария и создан буквально перед любыми другими объектами в БД.

Если у кого-либо есть понимание относительнопочему SQL Server так привередлив в отношении , когда созданы собственные функции и процедуры, не стесняйтесь оставлять комментарии или оставлять другие ответы.

0 голосов
/ 22 октября 2018

Это не будет хорошим ответом, но здесь идет ...

Чтобы отладить это, я бы загрузил полный запрос в SSMS и добавил BEGIN TRANSACTION вверху.На следующей строке поставьте -- ROLLBACK.Если ваш запрос не выполнен, вы можете выполнить откат и вернуться в чистое состояние (пустая база данных) с минимальной травмой.

По сути, просто начинайте удалять вещи, которые не требуются функции, в которой происходит сбой.Удалите некоторые операторы DDL, протестируйте выполнение и откат транзакций, пока они не будут выполнены без ошибок.Когда он выполняется без ошибок, вполне вероятно, что последний кусок кода, который вы удалили, вызывает вашу проблему.

Если вы удаляете несколько операторов DDL, что я бы сделал, вы можете получить более детальную информацию в этомточка.Я имею в виду, удалите целую кучу вещей, от которых ваша функция не зависит, а затем выполните весь запрос.Если это работает, откат, добавьте этот чанк обратно (Отменить / Ctrl Z), а затем получите более детальное удаление меньших чанков, по одному, пока вы не удалите отдельные операторы.

Рассматривайте это как поиск,При удалении одного оператора DDL ваш запрос заработал, вы нашли виновника.Вам просто нужно найти это утверждение.

Имея достаточно взад и вперед, вы сможете идентифицировать кусок кода, возможно, один оператор DDL, который вызывает вашу проблему.Если не сразу понятно, почему этот кусок кода вызывает у вас горе, опубликуйте его здесь или в новом вопросе, и, надеюсь, кто-то другой будет более полезным, чем я.

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