web-dev-qa-db-fra.com

TSQL Comment sortez-vous PRINT dans une fonction définie par l'utilisateur?

Fondamentalement, je veux utiliser l'instruction PRINT dans une fonction définie par l'utilisateur pour faciliter mon débogage.

Cependant, j'obtiens l'erreur suivante;

Utilisation non valide d'un opérateur à effet secondaire ou dépendant du temps dans 'PRINT' au sein d'une fonction.

Cela ne peut-il pas être fait?

Quoi qu'il en soit pour aider le débogage de ma fonction définie par l'utilisateur?

61
c00ke

Non désolé. Les fonctions définies par l'utilisateur dans SQL Server sont vraiment limitées, car elles doivent être déterministes. Autant que je sache.

Avez-vous essayé de déboguer le code SQL avec Visual Studio?

32
Tor Haugen

Astuce: générer une erreur.

declare @Day int, @Config_Node varchar(50)

    set @Config_Node = 'value to trace'

    set @Day = @Config_Node

Vous obtiendrez ce message:

La conversion a échoué lors de la conversion de la valeur varchar 'value to trace' en type de données int.

42
Estevez

J'ai eu tendance par le passé à travailler sur mes fonctions en deux temps. La première étape serait de les traiter comme des requêtes SQL assez normales et de m'assurer que j'en tire les bons résultats. Une fois que je suis convaincu qu'il fonctionne comme souhaité, je le convertirais en UDF.

24
TheTXI

J'ai contourné cela en réécrivant temporairement ma fonction sur quelque chose comme ceci:

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)
21
v1964

Utilisez la procédure étendue xp_cmdshell pour exécuter une commande Shell. Je l'ai utilisé pour imprimer la sortie dans un fichier:

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

Cela crée le fichier debuginfo.txt s'il n'existe pas. Il ajoute ensuite le texte "mytextoutput" (sans les guillemets) au fichier. Tout appel à la fonction écrira une ligne supplémentaire.

Vous devrez peut-être d'abord activer cette propriété db-server (par défaut = désactivé), ce qui, je le réalise, peut ne pas être du goût de dba pour les environnements de production.

7
LDerckx

Non tu ne peux pas.

Vous pouvez appeler un function à partir d'un stored procedure et déboguer un stored procedure (cela entrera dans le function)

4
Quassnoi

Vous pouvez essayer de renvoyer la variable que vous souhaitez inspecter. Par exemple. J'ai cette fonction:

--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

Lorsque je l'exécute. J'obtiens: Msg 241, Niveau 16, État 1, Ligne 1 La conversion a échoué lors de la conversion de la date et/ou de l'heure à partir d'une chaîne de caractères.

Arghh !!

Alors qu'est-ce que je fais?

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

Et je reçois '25'. Donc, je suis parti par un et donc je change pour ..

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

Voila! Maintenant ça marche :)

0
h.alex