SelectCommand
속성이 사용자로부터 텍스트 명령을 받는 쿼리 도구를 통해 런타임에 동적으로 지정되는 경우, 디자인 타임에 적절한 InsertCommand
, UpdateCommand
, 또는 DeleteCommand
를 지정하지 못할 수 있습니다. 단일 데이터베이스 테이블에 DataTable이(가) 맵핑되거나 해당 테이블에서 생성되는 경우, DbCommandBuilder 개체를 이용하여 DeleteCommand
의 InsertCommand
, UpdateCommand
, DbDataAdapter를 자동으로 생성할 수 있습니다.
자동 명령 생성을 가능하게 하려면 최소 요구 사항으로 SelectCommand
속성을 설정해야 합니다. 속성에 의해 SelectCommand
검색된 테이블 스키마는 자동으로 생성된 INSERT, UPDATE 및 DELETE 문의 구문을 결정합니다.
DbCommandBuilder는 INSERT, UPDATE 및 DELETE SQL 명령을 구성하는 데 필요한 메타데이터를 반환하기 위해 반드시 SelectCommand
을 실행해야 합니다. 따라서 데이터 원본에 대한 추가 이동이 필요하며 이로 인해 성능이 저하될 수 있습니다. 최적의 성능을 얻으려면 DbCommandBuilder를 사용하지 말고 명령을 명시적으로 지정하십시오.
또한 SelectCommand
는 하나 이상의 기본 키 또는 고유 열을 반환해야 합니다. 없는 경우 예외가 InvalidOperation
생성되고 명령이 생성되지 않습니다.
DataAdapter
와 연결될 때, null 참조인 경우 DbCommandBuilder의 속성인 InsertCommand
, UpdateCommand
, DeleteCommand
속성이 자동으로 생성됩니다. 속성에 Command
대해 이미 있는 경우 기존 Command
속성이 사용됩니다.
둘 이상의 테이블을 함께 조인하여 만든 데이터베이스 뷰는 단일 데이터베이스 테이블로 간주되지 않습니다. 이 경우 명령을 자동으로 생성하는 데 사용할 DbCommandBuilder 수 없습니다. 명령을 명시적으로 지정해야 합니다.
DataSet
를 데이터 원본에 다시 연결하기 위한 명령을 명시적으로 설정하는 방법에 대한 정보는 DataAdapters를 사용하여 데이터 원본 업데이트를 참조하세요.
출력 매개 변수를 업데이트된 DataSet
행에 다시 매핑하는 것이 좋습니다. 한 가지 일반적인 작업은 데이터 원본에서 자동으로 생성된 ID 필드 또는 타임스탬프를 검색하는 것입니다.
DbCommandBuilder 기본적으로 업데이트된 행의 열에 출력 매개 변수를 매핑하지 않습니다. 이 경우 명령을 명시적으로 지정해야 합니다. 자동으로 생성된 ID 필드를 삽입된 행의 열에 다시 매핑하는 예제는 ID 또는 일련 번호 값 검색을 참조하세요.
자동으로 생성된 명령에 대한 규칙
다음 표에서는 자동으로 생성된 명령이 생성되는 방법에 대한 규칙을 보여 줍니다.
명령어 | 규칙 |
---|---|
InsertCommand |
데이터 원본에 테이블의 RowState 및 Added 조건을 가진 모든 행을 삽입합니다. 업데이트할 수 있는 모든 열에 대한 값을 삽입합니다(ID, 식 또는 타임스탬프와 같은 열은 삽입하지 않음). |
UpdateCommand |
데이터 원본에서 RowState 이(가) Modified인 테이블의 모든 행을 업데이트합니다. ID 또는 식과 같이 업데이트할 수 없는 열을 제외한 모든 열의 값을 업데이트합니다. 데이터 원본의 열 값이 행의 기본 키 열 값과 일치하고 데이터 원본의 나머지 열이 행의 원래 값과 일치하는 모든 행을 업데이트합니다. 자세한 내용은 이 항목의 뒷부분에 있는 "업데이트 및 삭제에 대한 낙관적 동시성 모델"을 참조하세요. |
DeleteCommand |
RowState 이 Deleted인 테이블의 모든 행에 대해 데이터 원본에서 행을 삭제합니다. 열 값이 행의 기본 키 열 값과 일치하고 데이터 원본의 나머지 열이 행의 원래 값과 일치하는 모든 행을 삭제합니다. 자세한 내용은 이 항목의 뒷부분에 있는 "업데이트 및 삭제에 대한 낙관적 동시성 모델"을 참조하세요. |
업데이트 및 삭제에 대한 낙관적 동시성 모델
UPDATE 및 DELETE 문에 대한 명령을 자동으로 생성하는 논리는 낙관적 동시성을 기반으로 합니다. 즉, 레코드는 편집을 위해 잠겨 있지 않으며 다른 사용자 또는 프로세스에서 언제든지 수정할 수 있습니다. 레코드가 SELECT 문에서 반환된 후에 수정될 수 있지만 UPDATE 또는 DELETE 문이 실행되기 전에 자동으로 생성된 UPDATE 또는 DELETE 문에는 WHERE 절이 포함되므로 행이 원래 값을 모두 포함하고 데이터 원본에서 삭제되지 않은 경우에만 업데이트되도록 지정합니다. 이 작업은 새 데이터를 덮어쓰지 않도록 하기 위해 수행됩니다. 자동으로 생성된 업데이트가 삭제되었거나 원래 DataSet에 있는 값이 포함되지 않은 행을 업데이트하려고 시도하는 경우, 명령은 어떤 레코드에도 영향을 주지 않으며 DBConcurrencyException 예외가 발생합니다.
원래 값에 관계없이 UPDATE 또는 DELETE를 완료하려면 자동 명령 생성에 의존하지 않고 해당 값을 명시적으로 설정 UpdateCommand
DataAdapter
해야 합니다.
자동 명령 생성 논리의 제한 사항
자동 명령 생성에는 다음과 같은 제한 사항이 적용됩니다.
관련 없는 테이블만
자동 명령 생성 논리는 데이터 원본의 다른 테이블과의 관계를 고려하지 않고 독립 실행형 테이블에 대한 INSERT, UPDATE 또는 DELETE 문을 생성합니다. 따라서 데이터베이스의 외래 키 제약 조건에 참여하는 열에 대한 변경 내용을 제출하도록 호출 Update
할 때 오류가 발생할 수 있습니다. 이 예외를 방지하려면 외래 키 제약 조건과 관련된 열을 업데이트하기 위해 DbCommandBuilder를 사용하지 말고, 대신 작업을 수행하는 데 사용할 문장을 명시적으로 지정하십시오.
테이블 및 열 이름
대괄호로 구분된 경우에도 열 이름 또는 테이블 이름에 공백, 마침표, 따옴표 또는 기타 숫자가 아닌 문자와 같은 특수 문자가 포함된 경우 자동 명령 생성 논리가 실패할 수 있습니다. 공급자에 따라 QuotePrefix 및 QuoteSuffix 매개 변수를 설정하면 생성 논리가 공백을 처리할 수 있지만 특수 문자를 이스케이프할 수는 없습니다. catalog.schema.table 형식의 정규화된 테이블 이름이 지원됩니다.
CommandBuilder를 사용하여 SQL 문 자동 생성
그런 다음 DataAdapter
의 SelectCommand
속성을 먼저 설정하고, DataAdapter
객체를 생성한 후, CommandBuilder
가 자동으로 SQL 문을 생성할 수 있도록 DataAdapter
를 인수로 지정해야 합니다.
' Assumes that connection is a valid SqlConnection object
' inside of a Using block.
Dim adapter As SqlDataAdapter = New SqlDataAdapter( _
"SELECT * FROM dbo.Customers", connection)
Dim builder As SqlCommandBuilder = New SqlCommandBuilder(adapter)
builder.QuotePrefix = "["
builder.QuoteSuffix = "]"
// Assumes that connection is a valid SqlConnection object
// inside of a using block.
SqlDataAdapter adapter = new SqlDataAdapter(
"SELECT * FROM dbo.Customers", connection);
SqlCommandBuilder builder = new SqlCommandBuilder(adapter);
builder.QuotePrefix = "[";
builder.QuoteSuffix = "]";
SelectCommand 수정하기
INSERT, UPDATE 또는 DELETE 명령이 자동으로 생성된 후에 CommandText
의 SelectCommand
을 수정하면 예외가 발생할 수 있습니다. 수정된 SelectCommand.CommandText
내용에 삽입, 업데이트 또는 삭제 명령이 자동으로 생성될 때 사용된 것과 일치하지 않는 SelectCommand.CommandText
스키마 정보가 포함된 경우 메서드에 대한 DataAdapter.Update
향후 호출은 현재 테이블에서 참조하는 열에 더 이상 존재하지 않는 열에 SelectCommand
액세스하려고 시도할 수 있으며 예외가 throw됩니다.
CommandBuilder
의 RefreshSchema
메서드를 호출하여 CommandBuilder
에 의해 명령을 자동으로 생성하는 데 사용되는 스키마 정보를 새로 고칠 수 있습니다.
자동으로 생성된 명령을 확인하려면 GetInsertCommand
개체의 GetUpdateCommand
, GetDeleteCommand
, CommandBuilder
메서드를 사용하고 연결된 명령의 CommandText
속성을 검사하여 자동 생성된 명령에 대한 참조를 얻을 수 있습니다.
다음 코드 예제에서는 자동으로 생성 된 업데이트 명령을 콘솔에 씁니다.
Console.WriteLine(builder.GetUpdateCommand().CommandText)
Console.WriteLine(builder.GetUpdateCommand().CommandText);
다음 예제는 Customers
데이터 세트의 custDS
테이블을 다시 만듭니다.
RefreshSchema 메서드는 이 새 열 정보를 사용하여 자동으로 생성된 명령을 새로 고치기 위해 호출됩니다.
' Assumes an open SqlConnection and SqlDataAdapter inside of a Using block.
adapter.SelectCommand.CommandText = _
"SELECT CustomerID, ContactName FROM dbo.Customers"
builder.RefreshSchema()
custDS.Tables.Remove(custDS.Tables("Customers"))
adapter.Fill(custDS, "Customers")
// Assumes an open SqlConnection and SqlDataAdapter inside of a using block.
adapter.SelectCommand.CommandText =
"SELECT CustomerID, ContactName FROM dbo.Customers";
builder.RefreshSchema();
custDS.Tables.Remove(custDS.Tables["Customers"]);
adapter.Fill(custDS, "Customers");