2009-02-25 5 views
46

Fondamentalement, je veux utiliser PRINT instruction à l'intérieur d'une fonction définie par l'utilisateur pour faciliter mon débogage.TSQL Comment générer PRINT dans une fonction définie par l'utilisateur?

Cependant, j'obtiens l'erreur suivante;

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

Cela ne peut-il être fait? De toute façon pour aider mon débogage de fonction défini par l'utilisateur?

+2

une façon réelle à ce sujet, voir: http://stackoverflow.com/a/10721985/65223 –

Répondre

27

Non, désolé. Les fonctions définies par l'utilisateur dans SQL Server sont vraiment limitées, en raison d'une exigence qu'elles soient déterministes. Pas moyen de contourner, autant que je sache.

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

4

Non, vous ne pouvez pas.

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

+0

ou en faire une procédure stockée –

20

J'ai eu tendance dans le passé à travailler sur mes fonctions en deux étapes. La première étape consisterait à les traiter comme des requêtes SQL assez normales et à m'assurer que j'obtiens les bons résultats. Après que je suis convaincu qu'il fonctionne comme souhaité, alors je le convertirais en UDF.

+0

Voici comment je le fais aussi :) – Shiva

20

Je suis autour de cette réécriture par ma fonction temporairement à 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) 
+1

J'aime cette méthode, très Créatif. Renvoyez juste la sortie de débogage comme une autre colonne dans la table de retour :-). –

0

Vous pouvez essayer de retourner la variable que vous souhaitez vérifier. E.g. 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 

Quand je le lance .. je reçois: Msg 241, niveau 16, état 1, ligne 1 Échec de la conversion date et/ou le temps de 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 à ..

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

Voila! Maintenant cela fonctionne :)

29

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 pour tracer la' valeur varchar type de données int.

+3

Hack très simple qui fonctionne très bien. Meilleure réponse dans mon livre! –

5

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. Ensuite, il ajoute le texte "mytextoutput" (sans guillemets) au fichier. Tout appel à la fonction écrira une ligne supplémentaire.

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

+1

Ne pas oublier d'exécuter au préalable: EXEC sp_configure'xp_cmdshell », 1 GO RECONFIGURE GO – Jan

+0

Ne pas oublier d'exécuter au préalable: EXEC sp_configure 'Afficher les options avancées', 1 GO RECONFIGURE GO –