Comment puis-je attribuer une variable avec une déclaration préparée dans une procédure stockée?
J'ai mis en place une procédure stockée simple dans lequel les deux paramètres sont transmis par le biais de la rendre plus dynamique. J'ai fait cela avec une déclaration préparée dans la "les Deux Premiers Chiffres et le nombre de Dossiers".
Ce que je ne suis pas sûr, c'est si je peux faire la SET vTotalFT
section dynamique avec une déclaration préparée.
Pour le moment j'ai coder en dur les noms des tables et des champs. Je veux que mon vTotalFT
variable pour être affecté fondée sur une dynamique de l'instruction SQL, mais je ne suis pas sûr de la syntaxe. L'idée est que lorsque j'appelle ma procédure, je pourrais dire que c'table et de champ à utiliser pour l'analyse.
CREATE PROCEDURE `sp_benfords_ft_digits_analysis`(vTable varchar(255), vField varchar(255))
SQL SECURITY INVOKER
BEGIN
-- Variables
DECLARE vTotalFT int(11);
-- Removes existing table
DROP TABLE IF EXISTS analysis_benfords_ft_digits;
-- Builds base analysis table
CREATE TABLE analysis_benfords_ft_digits
(
ID int(11) NOT NULL AUTO_INCREMENT,
FT_Digits int(11),
Count_of_Records int(11),
Actual decimal(18,3),
Benfords decimal(18,3),
Difference Decimal(18,3),
AbsDiff decimal(18,3),
Zstat decimal(18,3),
PRIMARY KEY (ID),
KEY id_id (ID)
);
-- First Two Digits and Count of Records
SET @s = concat('INSERT INTO analysis_benfords_ft_digits
(FT_Digits,Count_of_Records)
select substring(cast(',vField,' as char(50)),1,2) as FT_Digits, count(*) as Count_of_Records
from ',vTable,'
where ',vField,' >= 10
group by 1');
prepare stmt from @s;
execute stmt;
deallocate prepare stmt;
SET vTotalFT = (select sum(Count_of_Records) from
(select substring(cast(Gross_Amount as char(50)),1,2) as FT_Digits, count(*) as Count_of_Records
from supplier_invoice_headers
where Gross_Amount >= 10
group by 1) a);
-- Actual
UPDATE analysis_benfords_ft_digits
SET Actual = Count_of_Records / vTotalFT;
-- Benfords
UPDATE analysis_benfords_ft_digits
SET Benfords = Log(1 + (1 / FT_Digits)) / Log(10);
-- Difference
UPDATE analysis_benfords_ft_digits
SET Difference = Actual - Benfords;
-- AbsDiff
UPDATE analysis_benfords_ft_digits
SET AbsDiff = abs(Difference);
-- ZStat
UPDATE analysis_benfords_ft_digits
SET ZStat = cast((ABS(Actual-Benfords)-IF((1/(2*vTotalFT))<ABS(Actual-Benfords),(1/(2*vTotalFT)),0))/(SQRT(Benfords*(1-Benfords)/vTotalFT)) as decimal(18,3));
OriginalL'auteur user1236443 | 2012-07-27
Vous devez vous connecter pour publier un commentaire.
D'abord, à l'utilisation dynamique de la table/colonne de noms, vous aurez besoin d'utiliser une chaîne/Déclaration Préparée À L'Avance comme votre première requête pour
@s
. Ensuite, pour obtenir la restitution de la valeur deCOUNT()
à l'intérieur de la requête que vous aurez besoin d'utiliserSELECT .. @vTotalFT
.Les éléments suivants doivent être tout ce que vous devez:
Veuillez noter: le nom de la variable a changé à partir de
vTotalFT
à@vTotalFT
. Il ne semble pas fonctionner sans la@
. Et aussi, la variable@vTotalFT
ne fonctionnent pas lorsqu'ils sont déclarés en dehors de/avant de la requête, de sorte que si vous rencontrez une erreur ou vide les résultats qui pourraient être une cause.Fonctionne un régal, merci.
Dope solution, mec..
Il y a un sérieux problème ici, le point de l'ensemble de l'aide d'une requête préparée est de désinfecter la saisie de l'utilisateur, mais vous êtes aveugle de la concaténation de vTable et vField dans l'instruction select. Cette réponse est ouvert à injection SQL.
Alors que je suis d'accord avec votre déclaration en général, je crois que vous avez mal lu l'intention de la question/réponse. La question est de savoir comment insérer dynamiquement table et les noms de colonnes qui ne peuvent pas être remplacés par des requêtes Préparées. Cela dit, ma réponse est adressée à l'OP du "comment", pas un side-réponse "c'est une liste d'étapes pour bien désinfecter table/colonne de noms directement dans MySQL". Si vous croyez que ma réponse à toujours être incorrect, n'hésitez pas à la modifier afin de la rendre la plus appropriée ou ajouter votre propre réponse à illustrer votre point =]
OriginalL'auteur newfurniturey
OriginalL'auteur Sachin Agrawal