Suite

Entrée utilisateur à valeurs multiples en tant que variable dans l'instruction SQL


J'essaie d'écrire un script qui prend la sélection d'un utilisateur comme paramètre et l'utilise dans le cadre de la fonction SelectByAttributes. Le paramètre représente les attributs de champ et est à valeurs multiples, et l'utilisateur peut en sélectionner une ou plusieurs.

Donc, ce que j'ai à ce stade, c'est la liste de tous les attributs disponibles, et chacun sélectionné comme défaut.

Voici également le code de validation de l'outil et les propriétés des paramètres :

import arcpy class ToolValidator(object): """Classe pour valider les valeurs des paramètres d'un outil et contrôler le comportement de la boîte de dialogue de l'outil.""" def __init__(self): """Configurer arcpy et la liste des paramètres de l'outil."" " self.params = arcpy.GetParameterInfo() def initializeParameters(self): """Affiner les propriétés des paramètres d'un outil. Cette méthode est appelée lorsque l'outil est ouvert.""" return def updateParameters(self): """ Modifiez les valeurs et les propriétés des paramètres avant d'effectuer la validation interne. Cette méthode est appelée chaque fois qu'un paramètre a été modifié.""" shape = "G:\_DPDSTEVENFIELD.shp" rows = arcpy.SearchCursor(shape) self .params[0].filter.list = trié(list(set(r.getValue('DPD_FLD_TY') pour r dans les lignes))) all = self.params[0].filter.list self.params[0]. value = all del rows return def updateMessages(self): """Modifier les messages créés par la validation interne pour chaque paramètre de l'outil. Cette méthode est appelée après validation interne.""" return

Je souhaite que l'utilisateur ait la possibilité d'exécuter l'outil avec plusieurs attributs sélectionnés ou avec un seul sélectionné, et de l'utiliser dans le cadre de l'instruction SQL au sein de la fonction SelectByAttribute. Par exemple, si l'utilisateur sélectionne "GAS" et "INCONNU", la fonction SelectByAttributes ressemblera à

arcpy.SelectLayerByAttribute_management(lyr,"NEW_SELECTION",""""DPD_FLD_TY" = 'GAS' OU "DPD_FLD_TY" ='INCONNU'""")

Ma question principale est donc la suivante : quel serait le code pour vérifier le nombre d'attributs sélectionnés et, sur cette base, l'instruction SQL contiendrait-elle la quantité appropriée d'instructions "OU" ? De plus, le paramètre serait-il considéré comme un seul, ou s'agirait-il de plusieurs paramètres, c'est-à-dire GetParameterAsText(0) vs. GetParameterAsText(0)… GetParameterAsText(3)

Je suis désolé si cela prête à confusion, mais je ne sais pas exactement par où commencer avec ce problème.

Voici comment je référence la couche:

import arcpy mxd = arcpy.mapping.MapDocument('CURRENT') mm = arcpy.mapping.ListDataFrames(mxd, "Layers")[0] lyr = arcpy.mapping.ListLayers(mxd, 'FIELD')[0] field = arcpy.GetParameterAsText(0)

Utilisez DPD IN ('Gas','Oil',") au lieu de plusieurs OR


Selon la réponse de @ FelixIP, utilisez un opérateur IN dans votre clause where.

Le paramètre multivaleur est passé sous la forme d'une seule chaîne délimitée par un point-virgule, c'est-à-dire"valeur1;valeur2;valeur3". Pour convertir cela au format requis pour l'opérateur IN, utilisez python split/list comprehension/join or replacement.

diviser/lister compréhension/rejoindre :

field = arcpy.GetParameterAsText(0) where_clause = '"DPD_FLD_TY" IN ' + "({})".format(','.join(["'{}'".format(f) pour f dans fields.split (';')]))

remplacement:

field = arcpy.GetParameterAsText(0) where_clause = '"DPD_FLD_TY" IN ' + "('{}')".format(fields.replace(";","','"))

Cela donne quelque chose comme :

print where_clause "DPD_FLD_TY" IN ('valeur1','valeur2','valeur3')

ÉDITER: Si votre nom de champ contient des espaces, ArcGIS l'enveloppera entre guillemets simples avant de passer à votre script. Supprimez les guillemets simples (avant de les ajouter à nouveau à tous les noms de champ) avec quelque chose comme :

field = arcpy.GetParameterAsText(0) fields=["'{}'".format(f.strip("'")) pour f dans fields.split(';')]DPD_FLD_TY" IN ({})". format(','.join(champs))

Exemples

Voici des exemples d'instructions SQL SELECT :

    Pour sélectionner toutes les colonnes d'une table ( Customers ) pour les lignes où la colonne Last_Name a Smith pour sa valeur, vous devez envoyer cette instruction SELECT au serveur principal :

Le serveur principal répondrait avec un jeu de résultats semblable à celui-ci :

L'ensemble de résultats suivant pourrait ressembler à :

Pour qu'une clause WHERE trouve des correspondances inexactes, ajoutez l'opérateur de correspondance de modèle LIKE . L'opérateur LIKE utilise le caractère générique % (symbole de pourcentage) pour faire correspondre zéro ou plusieurs caractères, et le caractère générique trait de soulignement ( _ ) pour correspondre exactement à un caractère. Par exemple:

    Pour sélectionner les colonnes First_Name et Nickname de la table Friends pour les lignes dans lesquelles la colonne Nickname contient la chaîne "brain", utilisez cette instruction :

L'ensemble de résultats suivant pourrait ressembler à :

L'ensemble de résultats pourrait ressembler à :


Comment déclarer une variable

  • Avant d'utiliser une variable dans un lot ou une procédure, vous devez déclarer la variable.
  • La commande DECLARE est utilisée pour DECLARE la variable qui agit comme un espace réservé pour l'emplacement mémoire.
  • Ce n'est qu'une fois la déclaration faite qu'une variable peut être utilisée dans la suite du batch ou de la procédure.

Syntaxe TSQL :

  • L'initialisation est une chose facultative lors de la déclaration.
  • Par défaut, DECLARE initialise la variable à NULL.
  • L'utilisation du mot-clé « AS » est facultative.
  • Pour déclarer plusieurs variables locales, utilisez une virgule après la première définition de variable locale, puis définissez le nom de la variable locale et le type de données suivants.

Exemples de déclaration d'une variable :

Requête : Avec « AS »

Requête : Sans 'AS'

Requête : DÉCLARER deux variables


Entrée utilisateur à valeurs multiples en tant que variable dans l'instruction SQL - Systèmes d'information géographique

Cela a fonctionné mais lorsque la longueur de la valeur name_product est supérieure à 3 caractères, il n'affiche aucun résultat.

Lorsque la valeur name_product est un caractère ASCII, il n'y a pas de problème, mais lorsque la valeur est Unicode, le problème se produit.

J'essaie d'utiliser cette syntaxe mais j'obtiens une erreur. Je ne comprends pas ce qui ne va pas ??

MODIFIER LA PROCÉDURE [dbo].[sp_GetRecord_czs] @Campaign varchar (30), @LASTREC int
COMME
DÉCLARER @requête COMME NVARCHAR(200)
DÉCLARER @ParamDefinition COMME NVARCHAR(100)
DÉCLARER @CallList COMME NVARCHAR (100)

SET @CallList = 'CallList_' + @Campagne
FIXER @LASTREC = LTRIM(STR(@LASTREC))

SET @query = 'SELECT TOP 30 ID, DEAL_REFERENCE, PHONE FROM @CallList WHERE ID > @LASTREC ORDER BY ID ASC'

SET @ParamDefinition = '@CallList NVARCHAR(50), @LASTREC int'
IMPRIMER @ParamDefinition
IMPRIMER @Campagne
IMPRIMER @CallList
IMPRIMER @requête
Exécutez sp_Executesql @query, @ParamDefinition, @CallList, @LASTREC

@CallList NVARCHAR(50), @LASTREC entier
AD_Format_10
CallList_AD_Format_10
SELECTIONNER LE TOP 30 ID, DEAL_REFERENCE, PHONE FROM @CallList WHERE ID > @LASTREC ORDER BY ID ASC
Msg 1087, niveau 16, état 1, ligne 1
Doit déclarer la variable de table "@CallList".

Le faire de la manière suggérée supprime tous les avantages des requêtes paramétrées et vous expose aux attaques par injection SQL.

Un exploit de preuve de concept adapté ci-dessous.

est-il possible que la valeur @SQLSTRING provienne d'une instruction MSSQL ?
par exemple SET @SQLSTRING = (SELECT SQLSTRING FROM MYTABLE) -- SQLSTRING inclut l'instruction SQL

Dans la procédure stockée, j'utilise le curseur sql pour ce curseur, je dois utiliser une requête SQL dynamique

déclarer curseur_test pour
select col1,col2 from table1 -- Cela devrait être une requête dynamique

test_curseur opn
récupérer le curseur_test dans @col1,@col2
tandis que @@fetch_status = 0
commencer
.
finir
fermer le curseur_test
désallouer le curseur_test

Je veux créer une procédure stockée pour créer plusieurs procédures de magasins,
en utilisant certains paramètres

Un échantillon à ce sujet, s'il vous plaît ?

Merci d'avance, cordialement.

Il est bon d'obtenir les détails des requêtes SQL dynamiques. Mais pourquoi les utilisons-nous ? Vous avez dit que nous les utilisions sur un scénario de recherche, pourquoi n'utilisez-vous pas plusieurs procédures stockées plutôt que d'écrire une requête dynamique ?

Ce sont les inconvénients que j'ai ressentis avec cette méthode

1 - L'écriture de requêtes dynamiques à l'intérieur de la procédure est très proche des attaques par injection SQL.
2 - Lorsqu'une procédure stockée est exécutée pour la première fois, SQL Server met en cache le plan d'exécution et sert la requête suivante à partir de ce cache. Cela donne beaucoup de différence de performance. Mais les requêtes dynamiques ne permettront pas de générer un plan d'exécution statique, et celui-ci sera compilé pour chaque requête.
3 - Il est très difficile de déboguer les requêtes
4 - Il masque les erreurs dans les requêtes puisqu'il est ajouté dans une chaîne

Merci d'avoir pris le temps de lire mon article et d'avoir posté votre suggestion, vos commentaires.

Oui, je suis d'accord avec votre point particulier selon lequel cela peut être réalisé à l'aide de plusieurs procédures stockées ou de plusieurs requêtes SELECT dans une procédure stockée. Que faire s'il existe de nombreux scénarios de recherche. Êtes-vous d'accord que l'écriture de 5,10 procédures stockées ou plus pour accomplir tout le scénario de recherche devient difficile à maintenir ? Lorsque le nombre de lignes de CODE augmente, la COMPLEXITÉ du maintien augmente également. il est plus facile de maintenir et de modifier une procédure stockée au lieu de 10 ou plus.

Oui, je suis d'accord avec votre déclaration (inconvénient - attaque par injection SQL). Mais cela peut être géré (ce que je n'ai pas expliqué dans l'article). Si les paramètres d'entrée sont utilisés de la manière que j'ai montrée dans l'exemple, la procédure est sujette aux attaques par injection SQL. Nous devons faire des efforts supplémentaires afin de protéger la procédure stockée contre l'exécution de CODE non autorisé en utilisant les fonctions suivantes (REPLACE, ISNULL, TRIM. ). L'utilisation appropriée de ces fonctions lors de l'ajout du paramètre Input à la chaîne SQL protégerait le SP (je crois) ainsi que les clauses SELECT, FROM, WHEREClause devraient être intégrées dans des variables séparées et concantées à la fin avant l'exécution.

Si la vitesse et les performances sont la priorité absolue, il faut éviter d'utiliser le SQL dynamique.

Et le débogage - nous devons prévoir du temps supplémentaire pour les tests et nous assurer qu'aucune partie n'est construite avec des erreurs de syntaxe.

Cela dépend de l'application que je code. Si je code une application pour laquelle des performances élevées sont attendues, j'utiliserais plusieurs procédures stockées. Ou j'utiliserais une procédure principale qui est référencée dans l'application et toutes les autres procédures seront appelées à partir de cette procédure dépend de la condition de recherche. Cette procédure principale sera imbriquée.

Ainsi, SQL Server peut mettre en cache tout le plan d'exécution des procédures imbriquées et le réutiliser lors de la prochaine requête. Ceci a été écrit en tant que pratique recommandée sur SQL Performance.com. Comme vous l'avez dit, ce sera un peu difficile à modifier lorsque nous avons beaucoup de critères de recherche, mais si les performances comptent vraiment, pourquoi n'ignorons-nous pas ce surcoût ?

S'il s'agit d'une petite application qui ne se soucie pas des performances et que nous avons suffisamment de temps pour formuler la requête en chaîne, j'accepterai votre méthode à 100%.

Je ne peux pas être tout à fait d'accord. Parce que nous manquons tous de temps. Il est donc très difficile de passer du temps à trouver des erreurs de syntaxe, ce qui est généralement fait par l'éditeur SQL.

Je ne critiquais pas vos efforts. J'ai eu de très mauvaises expériences avec les requêtes SQL dynamiques. Soit dit en passant, il sera intéressant d'examiner le plan d'exécution des requêtes pour les requêtes dynamiques contenues dans la procédure et une procédure normale qui fait le même travail. Vous trouverez la différence


-- modifié à 9h52 le mardi 23 octobre 2007

Général Actualités Suggestion Question Bug Réponse Blague Louange Rant Admin

Utilisez Ctrl+Gauche/Droite pour changer de message, Ctrl+Haut/Bas pour changer de fil, Ctrl+Maj+Gauche/Droite pour changer de page.


La commande EXEC exécute une procédure stockée ou une chaîne qui lui est transmise. Prière de se référer à Présentation et exemples d'EXEC SQL pour plus de détails et d'exemples sur la commande EXEC.

L'exemple suivant illustre la construction de l'instruction SQL à l'aide de la variable d'entrée et l'exécution de l'instruction SQL à l'aide de la commande EXEC.

Il existe une possibilité d'injection SQL lorsque vous construisez l'instruction SQL en concaténant des chaînes à partir de valeurs d'entrée utilisateur. J'espère couvrir l'injection SQL et certaines méthodes pour empêcher l'injection SQL dans mes futurs articles.

Nous devons faire attention aux valeurs nulles lors de la concaténation de chaînes à partir de paramètres à l'aide de l'opérateur « + ». Dans l'exemple ci-dessous, j'ai commenté l'instruction qui définit une valeur sur la variable "@pid”.

Par défaut, la variable "@pid” est NULL car nous n'avons défini aucune valeur. L'instruction finale construite après la concaténation est vide car l'opérateur « + » ne gère pas les valeurs nulles. Veuillez vous référer à l'image ci-dessous qui montre que la valeur finale de la variable "@SQL" est vide.

Dans ce cas, utilisez le ISNULL fonction pour construire une instruction SQL appropriée tout en concaténant des chaînes à l'aide de l'opérateur « + ».

La commande EXEC ne réutilise pas le plan compilé stocké dans le cache du plan. Exécutez la requête suivante et recherchez les plans mis en cache.


Syntaxe

    Input_Rowset
    Spécifie l'ensemble de lignes d'entrée sur lequel le réducteur opérera en tant que référence à un nom d'ensemble de lignes ou par une expression d'ensemble de lignes imbriquée :

Syntaxe

avec la sémantique suivante :

  • Ensemble de lignes
    Les deux sources d'ensemble de lignes les plus simples sont une variable d'ensemble de lignes telle que @rowset qui a été définie dans une instruction précédente du script ou une table qui a été créée dans le catalogue du compte :

Syntaxe

Une table peut être référencée soit avec son nom complet en 3 parties, dans le contexte de base de données actuel avec un nom en 2 parties, soit dans le contexte actuel de base de données et de schéma avec un nom en une seule partie.

  • Rowset_Expression
    U-SQL offre également la possibilité de réduire les expressions de requête imbriquées, les appels de fonction table ou l'interrogation d'ensembles de lignes externes. Suivez les liens pour plus de détails sur chacun.

Syntaxe

Le modèle de programmation UDO rend les valeurs et le schéma de l'ensemble de lignes d'entrée disponibles dans le contexte de l'implémentation du réducteur.

PRÉTRIER
La clause facultative PRESORT garantit que les lignes sont ordonnées par l'identifiant donné.

TOUS
L'option ALL indique que l'ensemble de lignes d'entrée deviendra le groupe à réduire. Similaire à un GROUP BY ALL .

ON Identifier_List
Cette option spécifie la liste des colonnes qui définissent les groupes.

Syntaxe

Si les colonnes ne font pas partie des colonnes de l'ensemble de lignes d'entrée ou ne sont pas comparables, une erreur est générée.

Syntaxe

  • Column_Definition_List
    Cette liste définit le schéma du réducteur. Les colonnes renvoyées sont définies comme une paire de noms de colonnes et de types de colonnes :

Syntaxe

Chaque colonne a un identificateur qui peut être un identificateur entre guillemets ou non. Une colonne est typée avec l'un des types U-SQL pris en charge par le réducteur.

Le modèle de programmation UDO met le schéma d'ensemble de lignes spécifié à la disposition de l'implémentation du réducteur. Une erreur est générée si le réducteur produit un schéma incompatible avec le schéma de retour spécifié.

Readonly_Clause
La clause facultative READONLY peut aider le programmeur UDO à écrire un code plus efficace. Pour plus d'informations sur la façon dont le programmeur UDO peut tirer parti de cet indice, consultez le Guide du développeur U-SQL C#.

La clause facultative READONLY spécifie que les colonnes sont en lecture seule pour le réducteur et seront transmises à la sortie en utilisant soit le même nom, soit le nom de colonne spécifié entre parenthèses. Seules les colonnes de la clause ON de l'expression de réduction peuvent être marquées READONLY , sinon l'erreur "E_CSC_USER_UDOREADONLYNOTKEYCOLUMN: Column '...' ne peut pas être marquée comme READONLY" est générée.

Syntaxe

Clause_requise
La clause facultative REQUIRED peut aider le programmeur UDO à écrire un code plus efficace. Pour plus d'informations sur la façon dont le programmeur UDO peut tirer parti de cet indice, consultez le Guide du développeur U-SQL C#.

La clause facultative REQUIRED spécifie que soit toutes les colonnes sont requises en entrée pour le réducteur (si spécifié avec * ) soit les colonnes spécifiées sont requises. Si une colonne spécifiée est suivie d'une liste de colonnes entre parenthèses, la colonne d'entrée n'est requise que si les colonnes de cette liste sont référencées à partir de la sortie.

Syntaxe

    Utilisation_Clause
    La clause USING spécifie quel réducteur doit être utilisé pour transformer l'ensemble de lignes d'entrée.

Syntaxe

La clause USING prend une expression C# qui renvoie une instance de IReducer . Les utilisateurs peuvent écrire le leur en implémentant un IReducer (voir U-SQL Programmability Guide: User-Defined Reducer pour plus de détails sur la façon d'écrire votre propre réducteur). Le plus souvent, l'expression UDO est soit l'instanciation d'une classe réductrice de la forme

ou l'invocation d'une méthode usine

où paramètre est un paramètre du réducteur.

Exemples

  • Les exemples peuvent être exécutés dans Visual Studio avec le plug-in Azure Data Lake Tools.
  • Les scripts peuvent être exécutés localement. Un abonnement Azure et un compte Azure Data Lake Analytics ne sont pas nécessaires lorsqu'ils sont exécutés localement.
  • Pour plus de simplicité, le ou les exemples avec du code défini par l'utilisateur utilisent Code-Behind pour la gestion de l'assemblage. Le principal avantage de Code-Behind est que l'outillage enregistrera le fichier d'assemblage et ajoutera automatiquement l'instruction REFERENCE ASSEMBLY. Pour utiliser l'enregistrement d'assembly au lieu de Code-Behind, consultez Utilisation d'assemblys : Procédure pas à pas d'enregistrement de code-behind et d'enregistrement d'assembly.

Réducteur défini par l'utilisateur - RangeReducer
L'exemple est une version légèrement modifiée de l'exemple donné à Comment combiner des plages qui se chevauchent à l'aide d'U-SQL ? Présentation des UDO U-SQL Reducer et usql/Examples/RangeReducer/RangeReducer/. Veuillez consulter l'article sur le réducteur pour plus de détails.
Le code c# est placé dans le fichier Code-Behind .cs associé. Voir l'utilisation dans la section suivante, au dessous de.

Utilisation du réducteur défini par l'utilisateur - RangeReducer
En utilisant le code-behind de la section précédente, au dessus.

Réducteur défini par l'utilisateur - SalesReducer
Le code c# est placé dans le fichier Code-Behind .cs associé. Voir l'utilisation dans la section suivante, au dessous de.

Utilisation du réducteur défini par l'utilisateur - SalesReducer
En utilisant le code-behind de la section précédente, au dessus.

Réducteur avec ORDER BY et FETCH
La clause ORDER BY avec FETCH permet la sélection d'un nombre limité de lignes en fonction de l'ordre spécifié. Cet exemple continue d'utiliser SalesReducer défini précédemment.


Regardez la table "Persons" :

identifiant Nom de famille Prénom Adresse Ville
1 Hansen Ola Timoteivn 10 Sandnes
2 Svendson Tove Borgvn 23 Sandnes
3 Pettersen Kari Storgt 20 Stavanger

Maintenant, nous voulons ajouter une colonne nommée "DateOfBirth" dans la table "Persons".

Nous utilisons l'instruction SQL suivante :

Notez que la nouvelle colonne, "DateOfBirth", est de type date et va contenir une date. Le type de données spécifie le type de données que la colonne peut contenir. Pour une référence complète de tous les types de données disponibles dans MS Access, MySQL et SQL Server, consultez notre référence complète sur les types de données.

La table "Persons" ressemblera maintenant à ceci :

identifiant Nom de famille Prénom Adresse Ville Date de naissance
1 Hansen Ola Timoteivn 10 Sandnes
2 Svendson Tove Borgvn 23 Sandnes
3 Pettersen Kari Storgt 20 Stavanger

Si vous souhaitez signaler une erreur, ou si vous souhaitez faire une suggestion, n'hésitez pas à nous envoyer un e-mail :

Votre message a été envoyé à W3Schools.

Top Tutoriels

Meilleures références

Principaux exemples

Cours Web

W3Schools est optimisé pour l'apprentissage et la formation. Les exemples pourraient être simplifiés pour améliorer la lecture et l'apprentissage. Les didacticiels, les références et les exemples sont constamment révisés pour éviter les erreurs, mais nous ne pouvons garantir l'exactitude totale de tout le contenu. En utilisant W3Schools, vous acceptez d'avoir lu et accepté nos conditions d'utilisation, notre politique de confidentialité et de cookies.