Je viens de publier du code en production qui provoque des erreurs de manière aléatoire. J'ai déjà corrigé le problème en changeant totalement la façon dont je faisais la requête. Cependant, cela me dérange toujours que je ne sais pas ce qui causait le problème en premier lieu alors je me demandais si quelqu'un pourrait connaître la réponse. J'ai la requête suivante à l'intérieur d'une procédure stockée. Je ne cherche pas de commentaires à propos de ce n'est pas une bonne pratique pour faire des requêtes avec des appels de fonctions imbriquées et des choses comme ça :-). Je veux juste vraiment savoir pourquoi cela ne fonctionne pas de manière cohérente. Au hasard, la fonction dans la requête retournera une valeur non numérique et provoquera une erreur sur la jointure. Cependant, si je réexécute immédiatement la requête, cela fonctionne correctement.Résultats incohérents SQL Server 2008
SELECT cscsf.cloud_server_current_software_firewall_id,
dbo.fn_GetCustomerFriendlyFromRuleName(cscsf.rule_name, np.policy_name) as rule_name,
cscsf.rule_action,
cscsf.rule_direction,
cscsf.source_address,
cscsf.source_mask,
cscsf.destination_address,
cscsf.destination_mask,
cscsf.protocol,
cscsf.port_or_port_range,
cscsf.created_date_utc,
cscsf.created_by
FROM CLOUD_SERVER_CURRENT_SOFTWARE_FIREWALL cscsf
LEFT JOIN CLOUD_SERVER cs
ON cscsf.cloud_server_id = cs.cloud_server_id
LEFT JOIN CLOUD_ACCOUNT cla
ON cs.cloud_account_id = cla.cloud_account_id
LEFT JOIN CONFIGURATION co
ON cla.configuration_id = co.configuration_id
LEFT JOIN DEDICATED_ACCOUNT da
ON co.dedicated_account_id = da.dedicated_account_id
LEFT JOIN CORE_ACCOUNT ca
ON da.core_account_number = ca.core_account_id
LEFT JOIN NETWORK_POLICY np
ON np.network_policy_id = (select dbo.fn_GetIDFromRuleName(cscsf.rule_name))
WHERE cs.cloud_server_id = @cloud_server_id
AND cs.current_software_firewall_confg_guid = cscsf.config_guid
AND ca.core_account_id IS NOT NULL
ORDER BY cscsf.rule_direction, cscsf.cloud_server_current_software_firewall_id
si vous remarquez la jointure
ON np.network_policy_id = (select dbo.fn_GetIDFromRuleName(cscsf.rule_name))
appelle une fonction.
est que la fonction:
ALTER FUNCTION [dbo].[fn_GetIDFromRuleName]
(
@rule_name varchar(100)
)
RETURNS varchar(12)
AS
BEGIN
DECLARE @value varchar(12)
SET @value = dbo.fn_SplitGetNthRow(@rule_name, '-', 2)
SET @value = dbo.fn_SplitGetNthRow(@value, '_', 2)
SET @value = dbo.fn_SplitGetNthRow(@value, '-', 1)
RETURN @value
END
qui appelle ensuite cette fonction:
ALTER FUNCTION [dbo].[fn_SplitGetNthRow]
(
@sInputList varchar(MAX),
@sDelimiter varchar(10) = ',',
@sRowNumber int = 1
)
RETURNS varchar(MAX)
AS
BEGIN
DECLARE @value varchar(MAX)
SELECT @value = data_split.item
FROM
(
SELECT *, ROW_NUMBER() OVER (ORDER BY (SELECT 1)) as row_num FROM dbo.fn_Split(@sInputList, @sDelimiter)
) AS data_split
WHERE
data_split.row_num = @sRowNumber
IF @value IS NULL
SET @value = ''
RETURN @value
END
qui appelle enfin cette fonction:
ALTER FUNCTION [dbo].[fn_Split] (
@sInputList VARCHAR(MAX),
@sDelimiter VARCHAR(10) = ','
) RETURNS @List TABLE (item VARCHAR(MAX))
BEGIN
DECLARE @sItem VARCHAR(MAX)
WHILE CHARINDEX(@sDelimiter,@sInputList,0) <> 0
BEGIN
SELECT @sItem=RTRIM(LTRIM(SUBSTRING(@sInputList,1,CHARINDEX(@sDelimiter,@sInputList,0)-1))), @sInputList=RTRIM(LTRIM(SUBSTRING(@sInputList,CHARINDEX(@sDelimiter,@sInputList,0)+LEN(@sDelimiter),LEN(@sInputList))))
IF LEN(@sItem) > 0
INSERT INTO @List SELECT @sItem
END
IF LEN(@sInputList) > 0
INSERT INTO @List SELECT @sInputList -- Put the last item in
RETURN
END
Quel est le type de données de np.network_policy_id? –
Vous avez affaire à des conversions numériques implicites ici. La fonction retourne un type de données 'varchar (12)' et vous effectuez des manipulations de chaîne dans votre udf, donc vous avez la probabilité d'obtenir des données non-numériques ET vous n'effectuez aucune validation pour vérifier si les données de retour sont numériques (en supposant c'est ce que tu veux). D'où l'erreur dans la jointure. – Kash
np.network_policy_id est un int. Je comprends que j'obtiens une erreur parce que la fonction renvoie un varchar (12) qui ne peut pas être converti en entier. Plus précisément, la fonction retourne la valeur 'NPG'. Ce que je ne comprends pas c'est pourquoi il retourne au hasard différentes choses. –