SQL Fonction à valeur de Table dans l'Instruction Select
SQL n'est pas mon truc mais j'ai essayé d'optimiser cette procédure stockée. Il avait plusieurs fonctions scalaires que j'ai essayé de modifier les fonctions de table parce que j'ai lu à plusieurs endroits que c'est un moyen plus efficace de le faire. Et maintenant, je les ai fait, mais pas vraiment sûr de la façon de mettre en œuvre ou si j'ai peut-être juste de ne pas créer correctement.
C'est la fonction que je vais appeler.
Alter FUNCTION [IsNotSenateActivityTableValue]
(
@ActivityCode int,
@BillId int,
@TextToDisplay varchar(max)
)
returns @T table(result varchar(max))
as
begin
DECLARE @result varchar(max);
declare @countcodes int;
declare @ishousebill int;
select @ishousebill = count(billid)
from BillMaster
where BillID = @BillID and Chamber = 'H'
If (@ishousebill = 0)
begin
SELECT @countcodes = count([ActivityCode])
FROM [HouseCoreData].[dbo].[ActivityCode]
where ActivityDescription not like '%(H)%' and ActivityType = 'S'
and [ActivityCode] = @ActivityCode
if (@countcodes = 0)
begin
set @result = 'test'
end
else
begin
set @result = 'test2'
end
end
else
begin
set @result = @TextToDisplay
end
RETURN
END
Et c'est ce que j'ai essayé de les appeler comme ça. Je préfère juste être capable de les mettre dans le top mais vraiment quelque chose qui fonctionne serait bon.
SELECT distinct
ActionDates.result as ActionDate
,ActivityDescriptions.result as ActivityDescription
FROM BillWebReporting.vwBillDetailWithSubjectIndex as vw
left outer join [BillWebReporting].[HasHouseSummary] as HasSummary on vw.BillID = HasSummary.BillID
outer APPLY dbo.IsNotSenateActivityDateTableValue(ActivityCode,vw.BillID,[ActionDate]) ActionDates
OUTER APPLY dbo.IsNotSenateActivityTableValue(ActivityCode,vw.BillID,[ActivityDescription]) as ActivityDescriptions
- Tag dit
mysql
, mais cela ressemble T-SQL et SQL Server. - Est-ce que votre fonction fonctionne réellement? Où avez-vous jamais insert into @T? Est-il seulement jamais signifié pour retourner une seule ligne?
- Aussi, le type le plus efficace de la fonction table est une table en ligne de la fonction (qui n'a qu'une
RETURN (SELECT ...);
et aucun de ces autres morceaux de code). Un multi-déclaration de la fonction table, comme celui que vous êtes en train d'écrire, est en fait sujettes à un grand nombre des mêmes problèmes de performances que vous essayez d'éviter. - Ok ya je n'ai pas l'avoir à l'insérer dans t est le problème de son travail maintenant, mais je vois certaines personnes, ne pas l'aimer. Est-il une meilleure façon d'aller à ce sujet?
- Veuillez vous abstenir de mettre des mots dans la bouche des gens. Personne n'a dit qu'ils n'aimaient pas votre code. Nous essayons simplement de vous aider, vous vous souvenez?
- Eh bien, il a déclaré que son sujette à beaucoup de problèmes que j'essayais d'éviter. Donc, je demandais juste si il avait une meilleure solution. Je vais prendre tout ce constructif, et en essayant d'obtenir la meilleure solution. Pas acusing gens de rien, désolé.
- Je viens de dire qu'un multi-déclaration de la table de l'UDF, il est peu probable pour résoudre quoi que ce soit (ni une table en ligne UDF).
Vous devez vous connecter pour publier un commentaire.
Table fonctions retournent un tableau, dans lequel, comme n'importe quel autre tableau, les lignes doivent être insérés.
Au lieu de faire
set @result = .....
, n':MODIFIER: Comme une note de côté, je ne comprends pas vraiment la raison de cette fonction à valeur de table. Vous essentiellement revenir un valeur.
inline
UDF, il est à table, pas scalaire, et inline fonctions définies par l'utilisateur sont beaucoup plus performant dans les scénarios où ils sont en train d'être exécutée plusieurs fois.Obtenir un compte juste pour voir si au moins une ligne qui existe est très cher. Vous devez utiliser
EXISTS
au lieu de cela, ce qui peut potentiellement court-circuit sans matérialisant l'ensemble.Ici est une façon plus efficace à l'aide d'une fonction table au lieu d'un multi-déclaration de la fonction table.
Bien sûr, il pourrait aussi être simplement un scalaire UDF...
Première de toutes les fonctions définies par l'utilisateur sont généralement de non-performant. Je ne suis pas sûr à propos de MySQL, mais dans Sql Server UDF est recompilé à chaque fois (POUR CHAQUE LIGNE DE SORTIE), il est exécutée, à l'exception de ce que l'on appelle inline Udf, qui ne disposent que d'une seule instruction select, qui est plié dans le SQL de la requête externe, il est inclus dans... et il est donc seulement une fois compilé.
MySQL n'ont les fonctions table en ligne, l'utiliser à la place... dans SQL Server, la syntaxe sera: