Parfois, lors de l'utilisation de tables non versionnées, il peut paraître plus simple d'interroger une table dans une base de données à l'aide de SQL (Structured Query Language) plutôt que d'utiliser l'un des outils de géotraitement. L'objet ArcSDESQLExecute prend en charge l'exécution de la plupart des instructions SQL et renvoie à l'utilisateur les résultats de ces instructions. L'objet renvoie une liste de listes lorsque l'instruction renvoie des lignes à partir d'une table ; pour les instructions qui ne renvoient pas de lignes, il renvoie une indication du succès ou de l'échec de l'instruction (True en cas de succès et None en cas d'échec). Les instructions qui renvoient une seule valeur à partir d'une ligne unique renverront la valeur dans un type approprié (chaîne, réel simple, réel simple).
Propriété | |
---|---|
transactionAutoCommit | Intervalle de validation automatique. Elle peut être utilisée pour forcer les validations intermédiaires après qu'un nombre spécifié d'entités a été modifié. |
Méthodes | |
---|---|
commitTransaction() | Aucune instruction DML n'est validée avant l'appel de la méthode commitTransaction. |
execute(sql_statement) | Envoie l'instruction SQL à la base de données via une connexion de géodatabse d'entreprise. Si la méthode execute est exécutée en dehors d'une transaction, une validation aura automatiquement lieu une fois l'instruction SQL DML (INSERT, UPDATE, DELETE) exécutée. |
rollbackTransaction() | Annule toute opération DML en revenant à la validation antérieure. |
startTransaction() | Pour contrôler le moment où vos modifications sont validées dans la base de données, appelez la méthode startTransaction avant d'appeler execute. Une transaction est alors lancée et aucune instruction DML ne sera validée avant l'appel de la méthode commitTransaction. |
La méthode execute envoie l'instruction SQL à la base de données via une connexion de géodatabase d'entreprise. Si la méthode execute est exécutée en dehors d'une transaction, une validation aura automatiquement lieu une fois l'instruction SQL DML (INSERT, UPDATE, DELETE) exécutée.
ArcSDESQLExecute prend en charge le modèle de transaction de géodatabase. Les transactions sont une propriété d'une connexion de géodatabase d'entreprise et lient les opérations afin qu'un ensemble complet de modifications soit enregistré ou rejeté. Par exemple, si un ensemble de parcelles est mis à jour dans un ordre particulier, vous pouvez utiliser une transaction pour définir le début et la fin des modifications afin que toutes les modifications soient réinjectées ensemble. Si un ensemble de modifications ne peut pas être inséré avec succès, l'ensemble de la transaction est rejetée. Toutes les transactions s'achèvent lors de la déconnexion d'un utilisateur. ArcSDESQLExecute utilise les fonctions d'API de la géodatabase d'entreprise fournies pour démarrer, valider et restaurer les transactions.
Si vous voulez contrôler le moment où vos modifications sont validées dans la base de données, appelez la méthode startTransaction avant d'appeler l'exécution. Une transaction est alors lancée et aucune instruction DML ne sera validée avant l'appel de la méthode commitTransaction. Une validation peut également se produire lorsque la connexion à la géodatabase d'entreprise prend fin (consultez la documentation spécifique au SGBD pour savoir comment chaque SGBD gère une déconnexion en cours de transaction). Dans une transaction, il est également possible de restaurer les opérations DML jusqu'à la validation antérieure.
Une propriété d'intervalle de validation automatique, transactionAutoCommit, est disponible. Elle peut être utilisée pour forcer les validations intermédiaires après qu'un nombre spécifié d'entités a été modifié.
Reportez-vous au guide de référence SQL spécifique à votre SGBD pour en savoir plus sur l'écriture d'instructions SQL.
Exemples
Exécution d'une liste d'instructions SQL
import sys
import arcpy
try:
# Make data path relative
arcpy.env.workspace = sys.path[0]
# Two ways to create the object, which also creates the
# connection to the enterprise geodatabase.
# Using the first method, pass a set of strings containing
# the connection properties:
# <serverName>, <portNumber>, <version>, <userName>, <password>
# arcpy.ArcSDESQLExecute("gpserver3","5151","#","toolbox","toolbox")
# Using the second method pass the path to a valid connection file
egdb_conn = arcpy.ArcSDESQLExecute(r"data\Connection to GPSERVER3.sde")
# Get the SQL statements, separated by ; from a text string.
sql_statement = arcpy.GetParameterAsText(0)
sql_statement_list = sql_statement.split(";")
print("+++++++++++++++++++++++++++++++++++++++++++++\n")
# For each SQL statement passed in, execute it.
for sql in sql_statement_list:
print("Execute SQL Statement: {0}".format(sql))
try:
# Pass the SQL statement to the database.
egdb_return = egdb_conn.execute(sql)
except Exception as err:
print(err)
egdb_return = False
# If the return value is a list (a list of lists), display
# each list as a row from the table being queried.
if isinstance(egdb_return, list):
print("Number of rows returned by query: {0} rows".format(
len(egdb_return)))
for row in egdb_return:
print(row)
print("+++++++++++++++++++++++++++++++++++++++++++++\n")
else:
# If the return value was not a list, the statement was
# most likely a DDL statement. Check its status.
if egdb_return == True:
print("SQL statement: {0} ran successfully.".format(sql))
else:
print("SQL statement: {0} FAILED.".format(sql))
print("+++++++++++++++++++++++++++++++++++++++++++++\n")
except Exception as err:
print(err)
Mise à jour conditionnelle à l'aide d'une transaction
# WARNING - DO NOT USE ON VERSIONED TABLES OR FEATURE CLASSES.
# DO NOT USE ON ANY enterprise geodatabase SYSTEM TABLES.
# DOING SO MAY RESULT IN DATA CORRUPTION.
import sys
import arcpy
try:
# Make data path relative (not relevant unless data is moved
# here and paths modified)
arcpy.env.workspace = sys.path[0]
# Column name:value that should be in the record.
sql_values = {"STREET_NAM": "'EUREKA'"}
# Value that is incorrect if found in the above column.
bad_val = "'EREKA'"
#List of tables to look in for the bad value.
tables = ["streetaddresses_blkA", "streetaddresses_blkB",
"streetaddresses_blkC"]
# Two ways to create the object, which also creates the connection
# to the enterprise geodatabase.
# Using the first method, pass a set of strings containing the
# connection properties:
# <serverName>, <portNumber>, <version>, <userName>, <password>
egdb_conn = arcpy.ArcSDESQLExecute("gpserver3", "5151", "#",
"toolbox", "toolbox")
# Using the second method pass the path to a valid enterprise geodatabase connection file
# arcpy.ArcSDESQLExecute("data\Connection to GPSERVER3.sde")
for tbl in tables:
print("+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++")
for col, val in list(sql_values.items()):
print("+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++")
# Check for the incorrect value in the column for the
# specific rows. If the table contains the incorrect value,
# correct it using the update SQL statement.
print("Analyzing table {0} for bad data: "
"Column:{1} Value: {2}".format(tbl, col, bad_val))
try:
sql = "select OBJECTID,{0} from {1} where {0} = {2}".format(
col, tbl, bad_val)
print("Attempt to execute SQL Statement: {0}".format(sql))
egdb_return = egdb_conn.execute(sql)
except Exception as err:
print(err)
egdb_return = False
if isinstance(egdb_return, list):
if len(egdb_return) > 0:
print("Identified {0} rows with incorrect data. Starting "
"transaction for update.".format(len(egdb_return)))
# Start the transaction
egdb_conn.startTransaction()
print("Transaction started...")
# Perform the update
try:
sql = "update {0} set {1}={2} where {1} = {3}".format(
tbl, col, val, bad_val)
print("Changing bad value: {0} to the good value: "
"{1} using update statement:\n {2}".format(
bad_val, val, sql))
egdb_return = egdb_conn.execute(sql)
except Exception as err:
print(err)
egdb_return = False
# If the update completed successfully, commit the
# changes. If not, rollback.
if egdb_return == True:
print("Update statement: \n"
"{0} ran successfully.".format(sql))
# Commit the changes
egdb_conn.commitTransaction()
print("Committed Transaction")
# List the changes.
try:
print("Displaying updated rows for "
"visual inspection.")
sql = "select OBJECTID" + \
",{0} from {1} where {0} = {2}".format(
col, tbl, val)
print("Executing SQL Statement: \n{0}".format(sql))
egdb_return = egdb_conn.execute(sql)
except Exception as err:
print(err)
egdb_return = False
if isinstance(egdb_return, list):
print("{0} rows".format(len(egdb_return)))
for row in egdb_return:
print(row)
print("++++++++++++++++++++++++++++++++++++++++\n")
else:
if egdb_return == True:
print("SQL statement: \n{0}\n"
"ran successfully.".format(sql))
else:
print("SQL statement: \n{0}\n"
"FAILED.".format(sql))
print("++++++++++++++++++++++++++++++++++++++++\n")
print("++++++++++++++++++++++++++++++++++++++++\n")
else:
print("SQL statement: \n{0}\nFAILED. "
"Rolling back all changes.".format(sql))
# Rollback changes
egdb_conn.rollbackTransaction()
print("Rolled back any changes.")
print("++++++++++++++++++++++++++++++++++++++++\n")
else:
print "No records required updating."
# Disconnect and exit
del egdb_conn
print("+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++")
except Exception as err:
print(err)