使用 ArcSDE 连接执行 SQL

处理尚未版本化的表时,使用结构化查询语言 (SQL) 查询数据库中的表要比使用某些地理处理工具进行查询更加容易。ArcSDESQLExecute 对象支持多数 SQL 语句的执行,并向用户返回这些语句的结果。对于语句从表返回行的情况,该对象将返回一列列表;对于不返回行的语句,该对象将返回语句成功或失败的指示(True 表示成功,None 表示失败)。

警告警告:
  • 不应使用 ArcGIS 软件以外的任何其他软件更改 ArcSDE 和 GDB 系统表。如果直接使用 SQL 对这些系统表进行编辑,则可能发生损坏。
  • 仅可通过版本化视图使用 SQL 对版本化数据进行编辑。
  • 对于在关系数据库管理系统 (DBMS) 中使用 DBMS 数据类型和表格式实现的地理数据库,可使用 DBMS 自带的 SQL 来处理该数据库中存储的信息。
  • 通过 SQL 访问地理数据库中的信息允许外部应用程序访问地理数据库管理的表格数据。这些外部应用程序可以是在 ArcObjects 以外的环境中开发的非空间数据库应用程序或自定义空间应用程序。但请注意,通过 SQL 访问地理数据库会忽略地理数据库功能,如拓扑、网络、地形、其他类或工作空间扩展模块。
  • 可使用触发器和存储过程等 DBMS 功能来维护某个地理数据库功能所需的表之间的关系。但是,如果对数据库执行 SQL 命令而不考虑此附加功能(如执行 INSERT 语句以向业务表添加记录),则会避开地理数据库功能并可能对地理数据库中数据之间的关系造成损坏。
  • 尝试访问或修改任何 ArcSDE 或 GDB 对象前,请先阅读有关对 DBMS 中的 ArcSDE 或 GDB 对象使用 SQL 的所有 ArcSDE 和地理数据库文档。

属性

transactionAutoCommit

自动提交间隔。此属性可用于修改完指定数量的要素后强制执行阶段性提交。

ArcSDESQLExecute 属性

方法

commitTransaction()

只有在调用 commitTransaction 方法后,才提交 DML 语句。

注注:

到 ArcSDE 的连接终止时,也可能发生提交(要了解每个 DBMS 对事务中出现断开连接的处理方式,请查看特定的 DBMS 文档)。

execute(sql_statement)

通过 ArcSDE 连接向数据库发送 SQL 语句。如果在事务的外面运行 execute,则执行完 SQL DML(INSERT、UPDATE、DELETE)语句后将自动发生提交。

rollbackTransaction()

将所有 DML 操作回滚到上一次提交。

startTransaction()

要控制向数据库提交更改的时间,请先调用 startTransaction 方法,然后再调用 execute。此方法用于启动事务,并且只有在调用 commitTransaction 方法后才提交 DML 语句。

ArcSDESQLExecute 方法

该 execute 方法通过 ArcSDE 连接向数据库发送 SQL 语句。如果在事务的外面运行 execute,则执行完 SQL DML(INSERT、UPDATE、DELETE)语句后将自动发生提交。

ArcSDESQLExecute 支持 ArcSDE 事务模型。事务是 ArcSDE 连接的一种属性,用于绑定操作,以便记录或拒绝整组更改。例如,如果正在以特定顺序对一组宗地进行更新,则可使用事务来定义更改的开始和结束,以便将所有更改一起提交。如果无法将一组更改成功插入,则会拒绝整个事务。所有事务在用户断开连接时结束。ArcSDESQLExecute 使用所提供的 ArcSDE API 函数来启动、提交及回滚事务。

要控制向数据库提交更改的时间,请先调用 startTransaction 方法,然后再调用 execute。此方法用于启动事务,并且只有在调用 commitTransaction 方法后才提交 DML 语句。到 ArcSDE 的连接终止时,也可能发生提交(要了解每个 DBMS 对事务中出现断开连接的处理方式,请查看特定的 DBMS 文档)。在事务中,还可将任何 DML 操作回滚到上一次提交。

自动提交间隔属性 transactionAutoCommit 可用。此属性可用于修改完指定数量的要素后强制执行阶段性提交。

有关编写 SQL 语句的帮助,请参阅 DBMS SQL 参考指南。

示例

执行一列 SQL 语句
import arcpy
from arcpy import env
import sys

try:
    # Make data path relative
    #
    env.workspace = sys.path[0]
    
    # Two ways to create the object, which also creates the connection to ArcSDE.
    #   Using the first method, pass a set of strings containing the connection properties:
    #   <serverName>,<portNumber>,<version>,<userName>,<password>
    #   sdeConn = arcpy.ArcSDESQLExecute("gpserver3","5151","#","toolbox","toolbox")
    #   Using the second method pass the path to a valid ArcSDE connection file
    #
    sdeConn = arcpy.ArcSDESQLExecute("data\Connection to GPSERVER3.sde")
    
    # Get the SQL statements, separated by ; from a text string.
    #
    SQLStatement = arcpy.GetParameterAsText(0)
    SQLStatementList = SQLStatement.split(";")
    
    print "+++++++++++++++++++++++++++++++++++++++++++++\n"

    # For each SQL statement passed in, execute it.
    #
    for sql in SQLStatementList:
        print "Execute SQL Statement: " + sql
        try:
            # Pass the SQL statement to the database.
            #
            sdeReturn = sdeConn.execute(sql)
        except Exception, ErrorDesc:
            print ErrorDesc
            sdeReturn = 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(sdeReturn, list):
            print "Number of rows returned by query: " + str(len(sdeReturn)), "rows"
            for row in sdeReturn:
                print row
            print "+++++++++++++++++++++++++++++++++++++++++++++\n"
        else:
            # If the return value was not a list, the statement was most likely a DDL statment. 
            #   Check its status.
            if sdeReturn == True:
                print "SQL statement: " + sql + " ran sucessfully."
                print "+++++++++++++++++++++++++++++++++++++++++++++\n"
            else:
                print "SQL statement: " + sql + " FAILED."
                print "+++++++++++++++++++++++++++++++++++++++++++++\n"
                
except Exception, ErrorDesc:
    print Exception, ErrorDesc
except:
    print "Problem executing SQL."

使用事务进行条件更新
# WARNING - DO NOT USE ON VERSIONED TABLES OR FEATURE CLASSES. 
#   DO NOT USE ON ANY ArcSDE or GDB SYSTEM TABLES.
#   DOING SO MAY RESULT IN DATA CORRUPTION.

import arcpy
from arcpy import env
import sys

try:
    # Make data path relative (not relevant unless data is moved here and paths modified)
    #
    env.workspace = sys.path[0]

    #Column name:value that should be in the record.
    #
    SQLvalues = {"STREET_NAM":"'EUREKA'"}

    #Value that is incorrect if found in the above column.
    #
    badVal = "'EREKA'"

    #List of tables to look in for the bad value.
    #
    tableList = ["streetaddresses_blkA","streetaddresses_blkB", "streetaddresses_blkC"]
    
    # Two ways to create the object, which also creates the connection to ArcSDE.
    #   Using the first method, pass a set of strings containing the connection properties:
    #   <serverName>,<portNumber>,<version>,<userName>,<password>
    #
    sdeConn = arcpy.ArcSDESQLExecute("gpserver3","5151","#","toolbox","toolbox")

    # Using the second method pass the path to a valid ArcSDE connection file
    #   sdeConn = arcpy.ArcSDESQLExecute("data\Connection to GPSERVER3.sde")

    for tbl in tableList:
        print "++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++"
        for col, val in SQLvalues.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 " + tbl + " for bad data: Column:" + col + " Value: " + badVal
            try:
                sql = "select OBJECTID," + col + " from " + tbl + " where " + col + " = " + badVal
                print "Attempt to execute SQL Statement: " + sql
                sdeReturn = sdeConn.execute(sql)
            except Exception, ErrorDesc:
                print ErrorDesc
                sdeReturn = False
            if isinstance(sdeReturn, list):
                if len(sdeReturn) > 0:
                    print "Identified " + str(len(sdeReturn)) + " rows with incorrect data. Starting transaction for update."
                    # Start the transaction
                    #
                    sdeConn.startTransaction()
                    print "Transaction started....."
                    # Perform the update
                    #
                    try:
                        sql = "update " + tbl + " set " + col + "=" + str(val) + " where " + col + " = " + badVal
                        print "Changing bad value: " + badVal + " to the good value: " + val + " using update statement:\n " + sql
                        sdeReturn = sdeConn.execute(sql)
                    except Exception, ErrorDesc:
                        print ErrorDesc
                        sdeReturn = False

                    # If the update completed sucessfully, commit the changes.  If not, rollback.
                    #
                    if sdeReturn == True:
                        print "Update statement: \n" + sql + " ran successfully."
                        # Commit the changes
                        #
                        sdeConn.commitTransaction()
                        print "Commited Transaction"

                        # List the changes.
                        #
                        try:
                            print "Displaying updated rows for visual inspection."
                            sql = "select OBJECTID," + col + " from " + tbl + " where " + col + " = " + val
                            print "Executing SQL Statement: \n" + sql
                            sdeReturn = sdeConn.execute(sql)
                        except Exception, ErrorDesc:
                            print ErrorDesc
                            sdeReturn = False
                        if isinstance(sdeReturn, list):
                            print len(sdeReturn), "rows"
                            for row in sdeReturn:
                                print row
                            print "+++++++++++++++++++++++++++++++++++++++++++++\n"
                        else:
                            if sdeReturn == True:
                                print "SQL statement: \n" + sql + "\nran successfully."
                                print "+++++++++++++++++++++++++++++++++++++++++++++\n"
                            else:
                                print "SQL statement: \n" + sql + "\nFAILED."
                                print "+++++++++++++++++++++++++++++++++++++++++++++\n"

                        print "+++++++++++++++++++++++++++++++++++++++++++++\n"
                    else:
                        print "SQL statement: \n" + sql + "\nFAILED.  Rolling back all changes."
                        # Rollback changes
                        #
                        sdeConn.rollbackTransaction()
                        print "Rolled back any changes."
                        print "+++++++++++++++++++++++++++++++++++++++++++++\n"
            else:
                print "No records required updating."
            
    # Disconnect and exit
    del sdeConn
    print "++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++"

except Exception, ErrorDesc:
    print Exception, ErrorDesc
except:
    print "Problem executing SQL."

相关主题


7/10/2012