ArcSDE 接続を使用した SQL の実行

バージョン対応登録されていないテーブルを操作するときに、ジオプロセシング ツールを使用するよりも、SQL(Structured Query Language)を使用してデータベース内の表を検索した方が簡単な場合があります。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()

変更内容がデータベースにコミットされるタイミングを制御するには、execute を呼び出す前に startTransaction メソッドを呼び出します。これによってトランザクションが開始され、commitTransaction メソッドが呼び出されるまで DML ステートメントはコミットされません。

ArcSDESQLExecute メソッド

execute メソッドは、ArcSDE 接続を経由してデータベースに SQL ステートメントを送信します。トランザクションの外部で execute を実行すると、SQL DML(INSERT、UPDATE、DELETE)ステートメントが実行された後でコミットが自動的に行われます。

ArcSDESQLExecute は ArcSDE のトランザクション モデルをサポートします。トランザクションは ArcSDE 接続およびバインド操作のプロパティで、一連の変更が全体としてまとめて記録または拒否されるようにするためのものです。たとえば、一連の土地区画を特定の順序で更新する場合は、トランザクションを使用して変更の開始と終了を定義することによって、すべての変更がまとめてポストされるようになります。一連の変更を正常に挿入できない場合は、トランザクション全体が拒否されます。ユーザが接続を切断するとすべてのトランザクションが終了します。ArcSDESQLExecute は標準の ArcSDE API 関数を使用して、トランザクションを開始、コミット、およびロールバックします。

変更内容がデータベースにコミットされるタイミングを制御するには、execute を呼び出す前に startTransaction メソッドを呼び出します。これによってトランザクションが開始され、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