Pourquoi les paramètres table doit être EN lecture seule, et pourquoi pas les paramètres de d'autres types de READONLY

dba.stackexchange https://dba.stackexchange.com/questions/120756

Question

Selon ce blog paramètres à une fonction ou une procédure stockée sont essentiellement passer par valeur si elles ne sont pas OUTPUT paramètres, et essentiellement traitée comme une plus sécuritaire de passer par référence si elles sont OUTPUT les paramètres.

Au début, je pensais que le but de forcer la TVP pour être déclaré READONLY a été de signaler clairement aux développeurs que la TVP peut pas être utilisé comme un OUTPUT paramètre, mais il doit y avoir plus de choses parce que nous ne pouvons pas déclarer la non-TVP comme READONLY.Par exemple les éléments suivants échoue:

create procedure [dbo].[test]
@a int readonly
as
    select @a

Msg 346, Niveau 15, État 1, Procédure de test
Le paramètre "@a" ne peut pas être déclaré EN lecture seule car il n'est pas un paramètre table.

  1. Depuis les statistiques ne sont pas stockées sur TVP quelle est la justification de la prévention des opérations DML?
  2. Est-ce lié à ne pas vouloir TVP être OUTPUT paramètres pour une raison quelconque?
Était-ce utile?

La solution

L'explication semble être liée à une combinaison de:a) un détail de la liés blog qui n'était pas mentionné dans cette question, b) la pragmatique de la les paramètres table de montage à l'intérieur de la façon dont les paramètres ont toujours été transmis dans et hors, c) et de la nature des variables de table.

  1. Le manque de détail contenues dans les liens blog est exactement la façon dont les variables sont passées dans et hors de Procédures Stockées et des Fonctions (qui a trait à la formulation de la Question de la "une plus sécuritaire de passer par référence si elles sont les paramètres de SORTIE"):

    TSQL utilise une copie dans/copie-out de la sémantique de passer des paramètres à des procédures stockées et des fonctions....

    [...] lorsque la procédure stockée a terminé l'exécution (sans frapper une erreur) une copie est faite qui met à jour le paramètre transmis avec toutes les modifications qui ont été apportées dans la procédure stockée.

    Le réel avantage de cette approche est dans l'erreur de cas.Si une erreur se produit dans le milieu de l'exécution de la procédure stockée, les modifications apportées aux paramètres de ne pas propager à l'appelant.

    Si la SORTIE de mot-clé n'est pas présente aucune copie n'est faite.

    La ligne du bas:
    Paramètres stockés procs ne reflètent jamais la partielle de l'exécution de la procédure stockée s'il a rencontré une erreur.

    La partie 1 de ce puzzle, c'est que les paramètres sont toujours passé "par valeur".Et, c'est seulement quand le paramètre est marqué comme OUTPUT et la Procédure Stockée se termine avec succès, la valeur actuelle est en fait envoyé en retour.Si OUTPUT les valeurs ont été réellement passé "par référence", alors que le pointeur à l'emplacement en mémoire de cette variable serait la chose qui a été adoptée, non pas la valeur elle-même.Et si vous faites passer le pointeur (c'est à direadresse de la mémoire), alors tous les changements sont immédiatement répercutées, même si la ligne suivante de la Procédure Stockée provoque une erreur et il abandonne l'exécution.

    Pour résumer la Partie 1:les valeurs des variables sont toujours copiés;elles ne sont pas référencées par leur adresse mémoire.

  2. Avec la Partie 1 à l'esprit, une politique de toujours copier les valeurs d'une variable peut conduire à des problèmes de ressources lors de la variable passée en est assez grand.Je n'ai pas testé pour voir comment blob types sont gérés (VARCHAR(MAX), NVARCHAR(MAX), VARBINARY(MAX), XML, et ceux qui ne doivent pas être utilisés plus: TEXT, NTEXT, et IMAGE), mais il est sûr de dire que n'importe quelle table de la transmission des données peut être assez important.Il ferait de sens que pour ceux en développement, la TVP de la fonctionnalité de désir d'une véritable "par référence" capacité à prévenir leur fraîcheur de la nouvelle fonctionnalité de la destruction d'une bonne santé nombre de systèmes (p. ex.pour une approche évolutive).Comme vous pouvez le voir dans la documentation qu'est ce qu'ils ont fait:

    Transact-SQL passe les paramètres de la table de routines par référence pour éviter de faire une copie des données d'entrée.

    Aussi, cette gestion de la mémoire préoccupation n'était pas un nouveau concept car il peut être trouvé dans la SQLCLR API qui a été introduit dans SQL Server 2005 (les paramètres table a été introduit dans SQL Server 2008).Lors du passage de NVARCHAR et VARBINARY données dans SQLCLR code (c'est à direles paramètres d'entrée sur la .NET des méthodes dans une SQLCLR de l'Assemblée), vous avez la possibilité d'aller avec la "valeur" de l'approche en utilisant SqlString ou SqlBinary respectivement, ou vous pouvez aller avec le "par référence" approche, en utilisant soit SqlChars ou SqlBytes respectivement.L' SqlChars et SqlBytes types de faciliter la diffusion des données dans le .NET CLR tels que vous pouvez tirer sur des petits morceaux de grandes valeurs, par opposition à la copie d'un ensemble de 200 MO (jusqu'à 2 GO, à droite) de la valeur.

    Pour résumer la Partie 2:Les paramètres table, de par leur nature, ont une propension à consommer beaucoup de mémoire (et donc de détériorer la performance), en cas d'hébergement dans le "toujours copier la valeur du modèle".Donc les paramètres table faire un véritable "passage par référence".

  3. La dernière pièce est pourquoi Partie 2 questions:pourquoi le passage d'une TVP vraiment "par référence" au lieu de faire une copie de changer quoi que ce soit.Et qui est répondu par l'objectif de la conception qui est à la base de la Partie 1:Les Procédures stockées qui ne s'est pas terminée correctement ne doit pas altérer, de quelque façon, tous les paramètres d'entrée, s'ils sont marqués comme OUTPUT ou pas.Permettant les opérations DML aurait un impact immédiat sur la valeur de la TVP tel qu'il existe dans le contexte de l'appel (depuis le passage par référence signifie que vous sont en train de changer la chose qui a été passé, et non pas une copie de ce qui a été transmis dans).

    Maintenant, quelqu'un, quelque part, est à ce point sans doute de parler de leur moniteur en disant: "eh Bien, juste construire dans un automagic facilité pour annuler les modifications apportées à la TABLE des paramètres, s'il en était passé dans la Procédure Stockée.Duh.Le problème est résolu." Pas si vite.C'est là que la nature des Variables de Table est livré en:les modifications apportées à la Table des Variables ne sont pas liées par des Opérations!Donc, il n'y a pas de façon de déployer les modifications.Et en fait, c'est un truc utilisé pour enregistrer les informations générées au sein d'une transaction si il doit y avoir un rollback :-).

    Pour résumer la Partie 3:Table des Variables ne permettent pas de "défaire" les changements dans le cas d'une erreur qui provoquait la Procédure Stockée pour l'abandonner.Et cela porte atteinte à l'objectif de la conception de l'avoir jamais paramètres reflétant l'exécution partielle (Partie 1).

Ergo: l' READONLY mot-clé est nécessaire pour éviter les opérations DML sur les paramètres table, car ils sont les Variables de Table qui sont réellement passées "par référence", et par conséquent, toute modification de ceux-ci serait immédiatement réfléchie, même si la Procédure Stockée rencontre une erreur, et il n'y a pas d'autre moyen de les en empêcher.

En outre, les paramètres des autres types de données peuvent pas utiliser READONLY parce qu'ils sont déjà des copies de ce qui a été transmis, et donc il ne serait pas protéger tout ce qui n'est pas déjà protégé.Que, et la façon dont les paramètres des autres types de travail a été conçu pour être en lecture-écriture, de sorte qu'il serait probablement encore plus de travail pour le modifier API pour inclure désormais une lecture seul concept.

Autres conseils

Wiki de la communauté réponse générée à partir d'un commentaire sur la question par Martin Smith

Il y a un actif élément de connexion (présenté par Erland Sommarskog) pour cela:

Détendre la restriction que les paramètres de la table doit être en lecture seule lors de la SPs s'appellent les uns les autres

La seule réponse par Microsoft jusqu'à présent, dit (italiques ajoutés):

Merci pour les commentaires sur cette.Nous avons reçu la même information à partir d'un grand nombre de clients. Permettant la table des paramètres de lecture/écriture implique un peu de travail sur le Moteur SQL ainsi que des protocoles clients. En raison du temps/de contraintes de ressources, ainsi que d'autres priorités, nous ne serons pas en mesure de prendre ce travail comme faisant partie de la version SQL Server 2008.Cependant, nous avons étudié cette question et ont fermement dans notre radar à aborder dans le cadre de la prochaine version de SQL Server.Nous apprécions et heureux de recevoir des commentaires ici.

Srini Acharya
Gestionnaire Principal De Programme
Moteur Relationnel SQL Server

Licencié sous: CC-BY-SA avec attribution
Non affilié à dba.stackexchange
scroll top