TSQL Как вы выводите PRINT в пользовательской функции?

В основном я хочу использовать PRINT оператор внутри пользовательской функции для облегчения отладки.

Однако я получаю следующую ошибку:

Недопустимое использование побочного или зависящего от времени оператора в PRINT внутри функции.

Разве этого нельзя сделать?

В любом случае, чтобы помочь отладке моей пользовательской функции?

Ответов (8)

Решение

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

Вы пробовали отлаживать код SQL с помощью Visual Studio?

Нет, ты не можешь.

Вы можете вызвать a function из a stored procedure и отладить a stored procedure (это войдет в function )

Вы можете попробовать вернуть переменную, которую хотите проверить. Например, у меня есть эта функция:

--Contencates seperate date and time strings and converts to a datetime. Date should be in format 25.03.2012. Time as 9:18:25.
ALTER FUNCTION [dbo].[ufn_GetDateTime] (@date nvarchar(11), @time nvarchar(11))
RETURNS datetime
AS
BEGIN

        --select dbo.ufn_GetDateTime('25.03.2012.', '9:18:25')

    declare @datetime datetime

    declare @day_part nvarchar(3)
    declare @month_part nvarchar(3)
    declare @year_part nvarchar(5)

    declare @point_ix int

    set @point_ix = charindex('.', @date)
    set @day_part = substring(@date, 0, @point_ix)

    set @date = substring(@date, @point_ix, len(@date) - @point_ix)
    set @point_ix = charindex('.', @date)

    set @month_part = substring(@date, 0, @point_ix)

    set @date = substring(@date, @point_ix, len(@date) - @point_ix)
    set @point_ix = charindex('.', @date)

    set @year_part = substring(@date, 0, @point_ix)

    set @datetime = @month_part + @day_part  + @year_part + ' ' + @time

    return @datetime
END

Когда я запускаю его ... Я получаю: Сообщение 241, уровень 16, состояние 1, строка 1 Ошибка преобразования при преобразовании даты и / или времени из символьной строки.

Аааааааааааааааааааааааа!

Итак, что мне делать?

ALTER FUNCTION [dbo].[ufn_GetDateTime] (@date nvarchar(11), @time nvarchar(11))
RETURNS nvarchar(22)
AS
BEGIN

        --select dbo.ufn_GetDateTime('25.03.2012.', '9:18:25')

    declare @day_part nvarchar(3)
    declare @point_ix int

    set @point_ix = charindex('.', @date)
    set @day_part = substring(@date, 0, @point_ix)

    return @day_part
END

И я получаю «25». Итак, я ухожу один и перехожу на ..

set @day_part = substring(@date, 0, @point_ix + 1)

Вуаля! Теперь работает :)

Совет: генерировать ошибку.

declare @Day int, @Config_Node varchar(50)

    set @Config_Node = 'value to trace'

    set @Day = @Config_Node

Вы получите это сообщение:

Ошибка преобразования при преобразовании значения varchar 'value to trace' в тип данных int.

Используйте расширенную процедуру xp_cmdshell для запуска команды оболочки. Я использовал его для вывода вывода в файл:

exec xp_cmdshell 'echo "mytextoutput" >> c:\debuginfo.txt'

Это создает файл debuginfo.txt, если он не существует. Затем он добавляет в файл текст «mytextoutput» (без кавычек). При любом вызове функции будет записана дополнительная строка.

Возможно, вам сначала потребуется включить это свойство db-server (по умолчанию = отключено), что, как я понимаю, может не понравиться dba для производственных сред.

На мой взгляд, всякий раз, когда я хочу распечатать или отладить функцию. Я скопирую его содержимое, чтобы запустить его как обычный сценарий SQL. Например

Моя функция:

create or alter function func_do_something_with_string(@input nvarchar(max)) returns nvarchar(max)
as begin
   -- some function logic content
   declare @result nvarchar(max)
   set @result = substring(@input , 1, 10)
   -- or do something else

   return @result
end

Затем я просто копирую и запускаю это из функции для отладки

    declare @input nvarchar(max) = 'Some string'      

    -- some function logic content
    declare @result nvarchar(max)
    set @result = substring(@input , 1, 10)
    -- this line is added to check while debugging
    print @result 
    
    -- or do something else
    -- print the final result
    print @result

Раньше я работал над своими функциями в два этапа. Первым этапом было бы обработать их как довольно обычные SQL-запросы и убедиться, что я получаю от них правильные результаты. После того, как я уверен, что он работает должным образом, я преобразовал бы его в UDF.

Я обошел это, временно переписав свою функцию примерно так:

IF OBJECT_ID ('[dbo].[fx_dosomething]', 'TF') IS NOT NULL
  drop function [dbo].[fx_dosomething];
GO

create FUNCTION dbo.fx_dosomething ( @x numeric )
returns @t table (debug varchar(100), x2 numeric)
as
begin
 declare @debug varchar(100)
 set @debug = 'printme';

 declare @x2 numeric
 set @x2 = 0.123456;

 insert into @t values (@debug, @x2)
 return 
end
go

select * from fx_dosomething(0.1)