2010-07-13 7 views
2

Je suis à la recherche d'un utilitaire qui convertira Oracle SQL en une chaîne pouvant être exécutée dynamiquement.Je recherche un utilitaire qui convertit une instruction SQL en une instruction SQL dynamique

Edit:

Oui, tenez compte de ce simple SQL

SELECT * FROM TABLE 
WHERE COLUMN_NAME = 'VALUE' 

J'ai un utilitaire qui, pour T-SQL qui convertit le SQL ci-dessus à un SQL synamic comme suit:

BEGIN 

DECLARE @Exe_String VarChar(2000) 
DECLARE @Qt   Char(1) 
DECLARE @Cr   Char(1) 

SET @Qt = Char(39) 
SET @Cr = Char(10) 

SET @Exe_String = 'SELECT * FROM TABLE ' + @Cr 
SET @Exe_String = @Exe_String + 'WHERE COLUMN_NAME = ' + @Qt + 'VALUE' + @Qt + '' + @Cr 

PRINT @Exe_String 

--Execute (@Exe_String) 

END 

Certes que le code généré est probablement meilleur, j'espère avoir l'idée.

Je suis à la recherche du même type de conversion pour Oracle SQL.

+0

Vous avez besoin d'un outil pour placer tout ce qui est entre guillemets simples et échapper les guillemets simples existants? –

+1

Sur le visage de celui-ci, il semble que vous voulez quelque chose qui est magique. Cela nous aiderait si vous pouviez donner un échantillon du type de déclaration SQL que vous souhaitez transformer, afin que nous puissions évaluer sa faisabilité. – APC

+0

@APC: Alors ...vous êtes un fan de Calvin & Hobbes, je vois =) –

Répondre

0

En tant que traduction brute de votre T-SQL PL/SQL

DECLARE 
    Exe_String VarChar(2000); 
    Qt CONSTANT Char(1) := CHR(39); 
    Cr CONSTANT Char(1) := CHR(10); 
BEGIN 
    exe_string := 'SELECT * FROM TABLE '||Cr; 
    exe_string := exe_string || 
       'WHERE COLUMN_NAME = ' || Qt || 'VALUE' ||Qt || '' ||Cr; 
    dbms_output.put_line(exe_string); 
    -- 
    EXECUTE IMMEDIATE exe_string; 
END; 

La différence évidente est que dans Oracle l'opérateur de concaténation des chaînes est || plutôt que +.

Personnellement, j'ai un petit paquet de manipulation de chaîne (appelons-le pstring) que j'utiliserais dans un cas comme celui-ci - inclut des fonctions comme enquote (chaîne), constantes standard pour newline, tabulation, etc. faire un remplacement de texte en style C.

exe_string := 
    pstring.substitute_text('SELECT * FROM %s \n WHERE %s = %s', 
       table_name,column_name,pstring.enquote(value)); 

Avez-vous pensé à utiliser des variables liées - à savoir: la valeur - plutôt que de traiter toutes les citations échapper internes? C'est une bonne défense contre l'injection SQL.

Évidemment, il y a quelques difficultés si vous avez un nombre variable de variables (vous devez utiliser DBMS_SQL pour les relier à l'instruction plutôt qu'un simple EXECUTE IMMEDIATE) mais pour votre cas simple, cela ressemblerait à ceci.

PROCEDURE (table_name IN VARCHAR2, column_name IN VARCHAR2) 
IS 
    Exe_String VarChar(2000); 
BEGIN 
    exe_string := 
     pstring.substitute_text('SELECT * FROM %s \n WHERE %s = :value', 
        table_name,column_name); 
    dbms_output.put_line(exe_string); 
    -- 
    EXECUTE IMMEDIATE exe_string USING pstring.enquote(value); 
END; 

Bien sûr, vous devez faire quelque chose avec les résultats de votre SQL.

EXECUTE IMMEDIATE exe_string INTO lresult USING pstring.enquote(value); 

Ce qui est difficile lorsque la forme de la table peut varier - encore une fois, vous devez regarder Type 4 SQL dynamique (DBMS_SQL).

1

Voici un outil que j'ai utilisé plusieurs fois. Vous devrez changer un peu la sortie pour l'exécuter, mais il va sans dire qu'il faut savoir comment échapper à toutes les tiques.

Sql Tuning

Après avoir cliqué sur le lien, il vous emmène directement sur le site et une page avec un échantillon SQL. Cliquez sur le bouton "SQL statique à SQL dynamique" et vous pouvez voir comment cela fonctionne. Ensuite, entrez votre propre SQL que vous voulez convertir et cliquez à nouveau sur le bouton. Supprimez les graduations supplémentaires (') à la fin et au début de chaque ligne à l'exception de la première et de la dernière ligne et les tuyaux (|) n'ont pas besoin d'être là non plus. J'espère que cela t'aides.