커맨드 수행¶
Fox DB Access 를 통해 데이터베이스에서 SQL 문장을 수행하거 저장 프로시저를 호출하기 위해서는 Execute-
시리즈의 메서드를 호출해야 합니다. Execute-
시리즈 메서드들은 내부적으로 Command
객체를 만들고 필요한 설정과 매개변수 지정을 하고 SQL 문장 혹은 저장 프로시저를 수행하고 그 결과를 반환합니다.
FoxDbAccess
클래스 및 그 파생 클래스들은 수행하고자 하는 데이터베이스 작업과 그 결과값에 따라 매우 다양한 Execute-
시리즈 메서드를 제공합니다. 매우 많은 메서드들을 빠르게 이해하는 방법으로 메서드 이름에 사용된 2 종류의 접미사를 이해하면 도움이 됩니다.
이 문서와 관련된 예제 코드는 다음 예제를 참조 하십시요.
- Fox Db Access Overview 예제 의 executing_command 프로젝트
Execute-
메서드 접미사¶
예를 들어 ExecuteSpDataSet
메서드는 Sp
접미사와 DataSet
접미사를 쓰는 Execute-
메서드입니다. Sp
접미사는 저장 프로시저를 수행한다는 의미의 접미사이며 DataSet
접미사는 수행결과를 DataSet
객체로 반환함을 나타내는 접미사 입니다.
수행 대상 접미사 ¶
첫번째 접미사는 Execute-
시리즈 메서드가 수행할 데이터베이스 작업을 나타냅니다.
-
-Sql-
: SQL 문장을 수행합니다. 전통적인 코딩 방식으로 이야기 하자면CommandType.Text
에 해당하는 작업을 수행합니다. 이들 메서드들은 수행할 SQL 문장을 첫번째 매개변수로 사용합니다. -
-Sp-
: 저장 프로시저를 수행합니다. 전통적인 코딩 방식으로는CommandType.StoredProcedure
에 해당하는 작업을 수행합니다. 이들 메서들은 수행할 저장 프로시저 이름을 첫번째 매개변수로 사용합니다.Note
사용하는 Npgsql 버전에 따라
ExecuteSp-
메서드가 호출하는 대상이 달라집니다. Npgsql 7.x 버전부터는ExecuteSp-
가 저장 프로시저를 호출하지만 그 이전 버전은 함수를 호출합니다. PostgreSQL 을 사용할 때 저장 프로시저보다 함수를 주로 사용한다면 다음 호출을 통해 Npgsql 7.x 이상 버전에서도ExecuteSp-
메서드가 함수를 호출하도록 지정할 수 있습니다. -
-Query-
: Fox Query 를 수행합니다. Fox Query 는.foxml
파일에서 SQL 문장, 데이터베이스 매개변수 정보를 포함하고 있습니다.ExecuteQuery-
메서드는 이러한 정보를 읽어Command
객체를 구성하고 수행하며 그 결과를 반환합니다.Fox Query 는 수행할 쿼리를 찾기 위한 쿼리 ID를 매개변수로 사용하며 이 쿼리 ID에서 읽어야 할
.foxml
파일과.foxml
파일 내의 쿼리를 알아냅니다.Fox Query 를 수행할 때 전달되는 DB 매개변수는
ExecuteSql-
,ExecuteSp-
등의 다른 메서드들과는 차이점이 있습니다. Fox Query 의 DB 매개변수에 대해서는 Fox Query DB 매개변수 항목을 참고 하십시요. -
-Command-
: 매개변수로 주어진Command
객체를 수행합니다. 이 메서드는CreateCommand
메서드에 의해 생성된Command
객체나 Fox DB Access 가 아닌 다른 API 를 통해 생성된Command
객체를 매개변수로 사용합니다.
수행 결과 접미사 ¶
두번째 접미사는 Execute-
시리즈 메서드가 반환하는 반환값을 나타냅니다. 이 접미사는 항상 수행할 커맨드 종류를 나타내는 접미사 뒤에만 사용됩니다.
-
-DataSet
: 수행 결과를DataSet
객체에 담아 반환합니다. 전형적으로SELECT
문장(들)을 수행하고 그 결과셋(resultset)을 반환합니다.DataSet
객체에 포함된DataTable
객체의 이름(DataTable.TableName
속성)은Table
이며FoxDbAccess
클래스의DefaultTableName
속성으로 변경할 수 있습니다. -
-List<T>
: 수행 결과를List<T>
객체로 반환합니다. 결과셋은T
타입으로 매핑 됩니다. 대개SELECT
류의 문장을 수행하고 그 결과를 담는T
타입의 객체 목록을 획득하는데 사용됩니다. 예를 들어, 다음 예제는 SELECT 문장으로 읽은 데이터를Product
객체에 매핑하여List<Product>
컬렉션으로 반환합니다. -
-NonQuery
: 수행 결과를 반환하지 않습니다.INSERT
,UPDATE
,DELETE
류의 문장을 수행하거나 저장 프로시저를 호출할 때 사용합니다.INSERT
/UPDATE
/DELETE
류의 명령이 영향 받은 행(row) 개수를 정수값으로 반환합니다.Note
PostgreSQL 은 Npgsql 의 버전에 따라 항상 -1 을 반환하는 경우도 있습니다.
-
-Scalar
: 수행 결과를 스칼라(scalar) 값으로 반환합니다. 즉, SQL 문장 혹은 저장 프로시저가 반환한 결과셋에서 첫번째 행, 첫번째 열을 스칼라 값으로 반환합니다. 나머지 결과셋은 무시됩니다.Note
스칼라 값을 반환하는 경우 데이터베이스마다 반환되는 타입이 다를 수 있습니다. 예를 들어
SELECT COUNT(*) FROM ...
값은 PostgreSQL 은 long 타입(Int64)으로 반환되지만 Oracle 은 decimal 타입으로 반환됩니다. 따라서 단순한 형변환은 데이터베이스에 따라 오류를 유발할 수 있습니다. 안전한 변환은Convert
클래스가 제공하는ToXXX
메서드를 사용하는 것입니다. -
-Reader
: 수행 결과를DataReader
객체로 반환합니다. 결과셋을 반환하는 SQL 문장 혹은 저장 프로시저를 수행하고 그 결과셋을 나타내는DataReader
객체를 반환합니다.FoxDbAccess
가 제공하는ExecuteXXXReader
메서드들은 가장 전형적으로DataReader
를 사용하는 패턴을 지원하고자자CommandBehavior
설정으로 기본값(None
)을 사용합니다. 다른CommandBehavior
설정을 사용하여DataReader
를 사용하고자 한다면FoxDbAccess
클래스의CreateCommand
메서드를 호출하여Command
객체를 생성하고 원하는CommandBehavior
설정을 사용하여ExecuteReader
메서드를 호출하십시요.Note
Command.ExecuteReader
메서드는 FoxDbAccess 에 의해 제어되지 않으므로 데이터베이스 연결을 자동으로 열어주지 않습니다. 따라서 위 코드에서는 명시적으로Open
메서드를 호출하고try~finally
문장에 의해Close
메서드를 호출합니다.FoxDbAccess
의 연결 관리에 대한 상세한 내용은 연결 관리 문서를 참고 하십시요. -
-
: 접미사가 없는 메서드는DataSet
객체를 매개변수로 받고 SQL 문장 혹은 저장 프로시저를 수행한 결과셋으로 주어진DataSet
객체를 채워넣습니다(fill). 여러개의 쿼리 결과를 하나의DataSet
객체에 담거나 여러 데이터베이스의 쿼리 결과를 하나의DataSet
객체에 담고자하는 경우에 유용합니다. 다음 예제는 PostgreSQL 과 Oracle 에SELECT
문을 수행하고 하나의DataSet
에 채워 넣는 코드 입니다.Note
위 예제 코드에서
ExecuteSql
메서드 호출은 테이블 이름 매핑(mapping)을 사용합니다. 접미사가 없는Execute-
메서드들은 내부적으로DataAdapter.Fill
메서드를 호출하며 이 메서드는 테이블 이름 매핑이 사용되지 않는 경우DataSet
의 첫번째DataTable
에 결과를 채웁니다. 따라서 테이블 이름 매핑을 사용하지 않으면 두ExecuteSql
메서드 호출은 하나의DataTable
에 병합(merge)됩니다. 테이블 이름 매핑에 대한 상세한 내용은 이 문서에서 다시 상세히 언급됩니다.Note
접미사가 없는
Execute-
메서드는 과거 .NET Framework 2.x 시절부터 TypedDataSet
지원을 위한 메서드이기도 합니다. TypedDataSet
은 최근에는 거의 사용하지 않는 데이터 컨테이너 입니다.
Execute-
메서드의 매개변수들¶
Execute-
시리즈 메서들에서 사용되는 여러 매개변수들에 대한 설명입니다. Execute-
메서드들은 매우 다양하기 때문에 사용하는 매개변수들도 매우 다양합니다. 여기서 설명되는 매개변수들은 Execute-
메서드들에 따라서 적용되는 여부가 달라질 수 있습니다.
수행 대상 매개변수¶
Exeucte
시리즈 메서드들의 첫번째 매개변수는 수행 대상을 나타내는 -Sql-
, -Sp
, -Query-
, -Command-
접미사들과 연관이 있습니다.
ExecuteSql-
메서드들의 첫번째 매개변수는 수행할 SQL 문장 입니다.ExecuteSp-
메서드들의 첫번째 매개변수는 수행할 저장 프로시저의 이름입니다.ExecuteQuery-
메서드들의 첫번째 매개변수는 수행할 Fox Query 에 대한 쿼리 ID 입니다.ExecuteCommand-
메서드들의 첫번째 매개변수는 수행할Command
객체 입니다.
DB 매개변수¶
ExecuteQuery-
메서드들과 일부 ExecuteCommand-
메서드를 제외한 Execute-
시리즈 메서드들은 SQL 문장/저장 프로시저에 적용할 DB 매개변수를 사용할 수 있습니다. 예를 들어, FoxDbAccess
클래스는 SQL 문장을 수행하여 DataSet
객체를 반환하는 ExecuteSqlDataSet
메서드를 다음과 같이 정의합니다.
SQL Server 를 위한 SqlParameter
, Oracle 을 위한 OracleParameter
, PostgreSQL 을 위한 NpgsqlParameter
등의 타입들들은 모두 IDataParameter
인터페이스를 구현하는 DbParameter
타입에서 파생되었습니다. 따라서 이들 타입에 대한 IEnumerable<IDataParameter>
를 지원하는 배열, 리스트(List<T>
) 등의 타입을 모두 사용할 수 있습니다.
배열이나 리스트를 사용하는 것보다 편리한 기능들을 갖는 FoxDbParamerCollection
객체를 사용하는 것이 더 권장됩니다. FoxDbParamerCollection
및 그 파생 클래스들(FoxSqlParameterCollection
, FoxOracleParameterCollection
, FoxNpgsqlParameterCollection
등)은 AddWithValue
메서드를 통해 컬렉션에 DB 매개변수를 손쉽게 추가할 수 있으며 null
값을 DBNull.Value
로 자동으로 변환하는 기능을 제공합니다. FoxDbParameterCollection
클래스는 IEnumerable<IDataParameter>
인터페이스를 구현하기 때문에 Execute-
시리즈 메서드에 사용할 수 있습니다. 더욱이 FoxDbParameterCollection
타입은 특정 데이터베이스에 의존적이지 않은 추상 클래스이므로 데이터베이스에 의존성이 없는 FoxDbAccess
클래스와 사용하기 적합합니다.
ExecuteCommand-
메서드들 중 일부는 IEnumerable<IDataParameter>
매개변수를 사용하지 않습니다. ExecuteCommand-
메서드는 CreateCommand
메서드나 Fox DB Access 를 사용하지 않고 다른 방법으로 생성된 Command
객체를 수행하는 메서드 입니다. 이렇게 생성된 Command
객체는 데이터베이스 매개변수에 대한 설정이 이미 완료되기 때문에 ExecuteCommand-
메서드에서 IEnumerable<IDataParameter>
매개변수가 포함되지 않는 것입니다.
Note
위 코드에서 CreateCommand
메서드 호출과 ExecuteCommand
메서드 호출을 한번에 호출하는 단축(short-cut) 메서드에서는 IEnumerable<IDataParameter>
매개변수가 포함될 수도 있습니다. 이 경우 첫번째 매개변수가 Command
객체가 아닌 CommandText
문자열(SQL 문장 혹은 저장 프로시저 이름)이 됩니다.
Fox Query 의 DB 매개변수 ¶
Fox Query 를 수행하는 메서드의 DB 매개변수는 작동 방식이 다릅니다. Fox Query 는 .foxml
파일에 SQL 문장 뿐만 아니라 매개변수 정보들도 기록해 두기 때문에 ExecuteQuery-
메서드들이 수행될 때 DB 매개변수들도 이 정보를 사용하여 자동으로 생성됩니다.
예를 들어, 다음과 같은 Fox Query 파일(.foxml
) 의 <statement>
태그가 있을 때 <parameters>
태그는 Command
객체의 Parameters
컬렉션에 DB 매개변수들을 설정합니다. 이 예제의 경우 product_id
, product_name
이라는 이름을 가진 DB 매개변수가 생성됩니다.
Information
ExecuteQueryDataSet
메서드가 수행하는 과정을 FoxDbAccess
가 제공하는 Fox Query 관련 API 들로 풀어서 다시 작성해보면 다음과 같습니다.
위 코드를 통해 Command
객체를 생성할 때 DB 매개변수가 이미 구성되어 있다는 것을 알 수 있습니다.
DB 매개변수가 이미 설정되어 있으므로 ExecuteQuery-
메서드를 수행하기 위해서는 DB 매개변수의 값(들)만을 전달하면 됩니다. 따라서 ExecuteQuery-
메서드에서는 DB 매개변수가 아닌 DB 매개변수 값(들)을 전달해야 합니다.
ExecuteQuery-
메서드의 parameterObject
매개변수에 사용할 수 있는 객체는 다음과 같습니다.
-
IDictionary
객체DB 매개변수 컬렉션에서 매개변수 이름에 대응되는
IDictionary
키/값을 찾아 DB 매개변수 값으로 사용합니다. Fox Biz/Data Service Web API 에서 사용되는 매개변수 컬렉션이IDictionary
를 사용하므로 이 때 많이 사용됩니다. -
DataRow
객체DB 매개변수 컬렉션에서 매개변수 이름에 대응되는
DataRow
컬럼을 찾아 그 값을 설정합니다.DataTable
의 변경 사항을 일괄적으로 추가/수정/삭제 할 때 많이 사용됩니다. -
일반 닷넷 객체
DB 매개변수 컬렉션에서 매개변수 이름에 대응되는 객체의 속성/필드를 찾아 그 값을 설정합니다. 엔티티 기반 앱에서 사용하거나 익명 타입(anonnymous type)을 사용하여 간단한 구현에 사용합니다.
테이블 이름 매핑(mapping)¶
수행한 SQL 문장 혹은 저장 프로시저가 여러 테이블을 반환하는 경우 DataSet
객체는 여러 DataTable
객체를 포함하게 됩니다. 여러 DataTable
의 이름은 기본적으로 DefaultTableName
속성값을 사용하고 뒤에 숫자가 붙는 형태로 적용됩니다. DefaultTableName
속성을 변경하지 않았다면 DataTable
의 이름들은 Table
, Table1
, Table2
등이 됩니다.
DefaultTableName
속성값을 ResultSet
으로 변경했다면 DataSet
에 포함된 DataTable
의 이름들은 ResultSet
, ResultSet1
, ResultSet2
가 됩니다.
-DataSet
접미사를 사용하는 Execute-
메서드들은 앞서 언급한 방식이외에도 DataTable
의 이름을 임의로 지정가능한 매핑 정보를 매개변수로 사용할 수 있습니다.
테이블 이름 매핑 정보가 주어지면 DataTable
의 이름은 테이블 이름 매핑 정보에 의해 지정됩니다.
외부 커맨드 수행 ¶
가끔씩 FoxDbAccess
클래스를 통해 Execute-
메서드들을 수행하기 어렵거나 FoxDbAccess
가 제공하는 CreateCommand
메서드를 사용하기 어려울 때가 있을 수 있습니다. 예를 들어 CommandBuilder
클래스를 통해 INSERT
/UPDATE
/DELETE
문장을 포함하는 Command
객체를 사용하고자 하는 상황입니다. 다음 예제는 CommandBuilder
클래스를 통해 INSERT
SQL 문장을 포함하는 커맨드 객체를 생성하고 수행하는 예를 보여 줍니다.
Fox DB Access 가 아닌 외부 API 를 통해 생성된 Command
객체를 FoxDbAccess
클래스를 통해 수행할 때 얻을 수 있는 장점은 FoxDbAccess
객체가 제공하는 연결 관리 기능, 트랜잭션 처리 기능의 적용을 받을 수 있으며 해당 Command
객체에 대한 DB 프로파일 정보도 같이 얻을 수 있기 때문입니다.
Summary¶
Fox DB Access 는 SQL 문장을 수행하거나 저장 프로시저를 편리하게 호출하기 위해 매우 다양한 Execute-
메서드들을 제공합니다. SQL 문장을 수행하기 위한 ExecuteSql-
메서드들, 저장 프로시저 호출을 위한 ExecuteSp-
메서드들을 비롯하여 .foxml
파일에서 Fox Query 를 읽어 들어 수행하는 ExecuteQuery-
메서드들과 다양한 방법을 통해 생성된 Command
객체를 수행하는 ExecuteCommand-
메서드들도 제공됩니다.
이들 메서드들은 쿼리 수행 결과로서 DataSet
객체, 스칼라 값, DataReader
객체를 반환하거나 쿼리 수행 결과를 무시할 수도 있습니다.
각 Execute-
메서드들은 수행하고자 하는 대상(SQL 문장, 저장 프로시저, Fox Query 등)과 수행 결과(DataSet
, DataReader
등)에 따라 매개변수, 작동 방식에서 약간의 차이점이 있지만 이 문서에서 설명한 내용을 숙지하면 사용하는데 어려움은 없을 것입니다. 이들 Execute-
메서드들을 통해 개발자는 전통적인 데이터 액세스 방법보다 훨씬 더 적은 노력과 시간으로 보다 데이터 액세스를 수행할 수 있습니다.