-1
votes

Comment déboguer l'erreur de procédure `doit déclarer la variable de table" @ Table1 "`

CREATE PROC AllRowsAndagain
@table1 NVARCHAR(128)

AS
BEGIN
  select count(*) FROM @table1  
END; 
I am getting this error - 
  Msg 1087, Level 16, State 1, Procedure AllRowsAndagain11, Line 9 [Batch Start Line 0]
  Must declare the table variable "@table1". 
I want to pass the tablename as a parameter here

4 commentaires

Vous essayez d'interroger la variable @ table1 . Qu'essayez-vous d'atteindre? Comptez le nombre de lignes dans une table donnée et stockez-le @ table1 ou que vous souhaitez transmettre le nom de la table comme paramètre dans votre procédure?


Je veux transmettre le nom de la table comme paramètre dans la procédure


Vous ne pouvez pas; Un nom de table (objet) doit être un littéral, vous ne pouvez pas le remplacer par une variable. Cela ressemble à un problème xy, quel est le problème que vous essayez de résoudre ici? (Vous pouvez le faire avec SQL dynamique, mais je soupçonne que vous avez un problème différent, vous devez réellement résoudre.)


Vous ne pouvez pas paramétrer les objets sans utiliser SQL dynamique. Chaque fois que je vois des procédures comme celle-ci, je dois demander ce que vous essayez vraiment de résoudre parce que c'est presque toujours une indication d'un processus non bien conçu.


3 Réponses :


2
votes

Vous ne pouvez pas utiliser une variable pour remplacer le nom d'une table. Vous auriez besoin d'utiliser du code dynamique pour cela. Heureusement, il existe un moyen plus efficace de récupérer le nombre de lignes de n'importe quelle table.

CREATE PROC AllRowsAndagain
(
  @table1 NVARCHAR(128)
)
AS
BEGIN

  SELECT SUM(row_count) AS row_count
  FROM sys.dm_db_partition_stats
  WHERE OBJECT_NAME( object_id) = @table1
  AND index_id IN (0,1);
END; 


7 commentaires

Merci pour cela, est-il possible d'avoir plusieurs instructions sélectionnées dans cela et de les syndicaliser?


Oui. Ou vous pouvez utiliser pour avoir une seule sélection.


Pouvez-vous s'il vous plaît me montrer un exemple avec en haut de ce procès?


docs.microsoft.com/en-us/sql/t-sql/language-Elements/.../a>


Je suis conscient de la façon dont les travaux, mais ce que je voulais, c'est que si je dois utiliser une autre table, dites Table2 et que vous avez un autre SELECT de ce tableau2, puis-je avoir ces deux ces deux éléments sélectionnés dans un seul PROC sous le début et la fin?


Essayez-vous de résoudre le premier problème de votre autre question? Stackoverflow.com/Questtions/58113752/...


Oui, correct, j'ai essayé d'avoir plusieurs instructions de sélection à l'intérieur d'un seul procédé



2
votes

Comme beaucoup ont fait allusion dans les commentaires dont vous aurez besoin d'utiliser SQL dynamique. SQL dynamique cependant peut être dangereux et vous devriez essayer d'éviter l'utilisation.

Pour répondre à votre question, vous devez utiliser quelque chose comme ceci: xxx

Vérification de la table contre Information_schema.Thables rend votre SQL dynamique beaucoup plus sûr. Comme il n'exécutera que la déclaration dynamique si une table a été transmise comme une variable et non une déclaration malveillante.


8 commentaires

Vous manquez le type de données pour votre paramètre (mais sinon +1).


Il suffit d'ajouter le type de données! Merci beaucoup.


Merci pour cela et il a l'air propre, est-ce que nous pouvons ajouter plusieurs déclarations sélectionnées sur ce processus dynamique SQL?


+ 'Union' + 'Select * à partir de' + @safetablename J'ai essayé d'ajouter à l'affiche de l'instruction SELECT, mais sa donnez-moi une erreur, toute aide?


Avez-vous retiré le demi-point de la fin de la déclaration SELECT?


Déclarez @sql comme nvarchar (max) = 'Select Count (*) de' + SafeBreName + 'Union Select * de' + SafetablEname doit être capable de le faire si c'est ce que vous voulez.


et évidemment le symbole @ devant la variable SafeBrename. Ne me laisserais pas ajouter plus d'un symbole


Utilisation de Union pour renvoyer le nombre de lignes et les lignes nécessitent que les deux requêtes renvoient le même nombre de colonnes et que les types de données de colonne sont compatibles. Une procédure stockée peut renvoyer plusieurs joints. Il n'est donc pas nécessaire de combiner les requêtes.



-3
votes

Votre problème est que vous essayez de compter le nombre de lignes dans une variable de chaîne. Semble un peu Ott mais vous êtes ici .......

CREATE PROC AllRowsAndagain
@table1 NVARCHAR(128)

AS
BEGIN
  --DECLARE A VARIABLE TO HOLD THE STATEMENT
  DECLARE @Statement NVARCHAR(1024);

  --BUILD THGE STATMENT USING THE TABLE NAME YOU PASS IN
  SET @Statement = CONCAT('SELECT COUNT(*) FROM ', @table1, ';');
  --ONLY RUN FIRST COMMAND
  SET @Statement = SUBSTRING(@Statement, 1, CHARINDEX(';', @Statement));
  --RUN THE SQL
  exec sp_executesql @Statement;
END; 


7 commentaires

Connaissez-vous de petites tables de Bobby?


Je ne suis pas au courant des petites tables de Bobby, qu'est-ce qu'ils sont? Puis-je avoir plusieurs instructions sélectionnées dans cela aussi? comme plusieurs relevés de jeu?


MDR. Bobby-tables.com Le problème est que votre code est large à l'injection SQL. Si je vous transmettez la valeur "Sys.Tables; Drop Table Clients;" Devinez ce qui arrive à votre table des clients?


Comment cela a-t-il eu une uvote et pourquoi ...? L'injection n'est pas quelque chose qui devrait être loué.


Comparendu - Humblistes excuses ... Je vais me flageller moi-même plus tard. J'ai pris une autre approche en n'exécutant que la première déclaration.


Conseil: la meilleure pratique lors de l'assemblage des noms d'objet dans des instructions SQL dynamiques consiste à utiliser QUANNAME () Pour éviter les problèmes avec des noms impairs, par exemple Nouveau tableau avec un espace ou des mots réservés tels que de .


Le réel avantage de quotename , @habo, est que cela diminuera de manière significative l'exposition à l'injection (lorsqu'elle est utilisée correctement).