class RSqlStatement |
Represents an SQL statement.
An object of this type can be used to execute all types of SQL statements; this includes SQL statements with parameters.
If a SELECT statament is passed to RSqlStatement::Prepare(), then the returned record set is forward only, non-updateable.
There are a number of ways that this object is used; here are some examples.
CASE 1 - the execution of a SQL statement, which does not return record set:
RSqlDatabase database; ......... RSqlStatement stmt; TInt err = stmt.Prepare(database, _L("INSERT INTO Tbl1(Fld1) VALUES(:Val)")); TInt paramIndex = stmt.ParameterIndex(_L(":Val")); for(TInt i=1;i<=10;++i) { err = stmt.BindInt(paramIndex, i); err = stmt.Exec(); err = stmt.Reset(); } stmt.Close();
The following pseudo code shows the general pattern:
<RSqlStatement::Prepare()> [begin:] <RSqlStatement::Bind<param_type>()> <RSqlStatement::Exec()> [<RSqlStatement::Reset()>] [<RSqlStatement::Bind<param_type>()>] [<Goto :begin>]
CASE 2 - the execution of a SQL statement, which returns a record set:
RSqlDatabase database; ......... RSqlStatement stmt; TInt err = stmt.Prepare(database, _L("SELECT Fld1 FROM Tbl1 WHERE Fld1 > :Val")); TInt paramIndex = stmt.ParameterIndex(_L(":Val")); err = stmt.BindInt(paramIndex, 5); TInt columnIndex = stmt.ColumnIndex(_L("Fld1")); while((err = stmt.Next()) == KSqlAtRow) { TInt val = stmt.ColumnInt(columnIndex); RDebug::Print(_L("val=%d\n"), val); } if(err == KSqlAtEnd) <OK - no more records>; else <process the error>; stmt.Close();
The following pseudo code shows the general pattern:
<RSqlStatement::Prepare()> [begin:] <while (RSqlStatement::Next() == KSqlAtRow)> <do something with the records> if(err == KSqlAtEnd) <OK - no more records>; else <process the error>; [<RSqlStatement::Reset()>] [<RSqlStatement::Bind<param_type>()>] [<Goto begin>]
CASE 3.1 - SELECT statements: large column data processing, where the data is copied into a buffer supplied by the client:
RSqlDatabase database; ......... RSqlStatement stmt; TInt err = stmt.Prepare(database, _L("SELECT BinaryField FROM Tbl1")); TInt columnIndex = stmt.ColumnIndex(_L("BinaryField")); while((err = stmt.Next()) == KSqlAtRow) { TInt size = stmt. ColumnSize(columnIndex); HBufC8* buf = HBufC8::NewL(size); err = stmt.ColumnBinary(columnIndex, buf->Ptr()); <do something with the data>; delete buf; } if(err == KSqlAtEnd) <OK - no more records>; else <process the error>; stmt.Close();
CASE 3.2 - SELECT statements: large column data processing, where the data is accessed by the client without copying:
RSqlDatabase database; ......... RSqlStatement stmt; TInt err = stmt.Prepare(database, _L("SELECT BinaryField FROM Tbl1")); TInt columnIndex = stmt.ColumnIndex(_L("BinaryField")); while((err = stmt.Next()) == KSqlAtRow) { TPtrC8 data = stmt.ColumnBinaryL(columnIndex); <do something with the data>; } if(err == KSqlAtEnd) <OK - no more records>; else <process the error>; stmt.Close();
CASE 3.3 - SELECT statements, large column data processing (the data is accessed by the client without copying), leaving-safe processing:
RSqlDatabase database; ......... RSqlStatement stmt; TInt err = stmt.Prepare(database, _L("SELECT BinaryField FROM Tbl1")); TInt columnIndex = stmt.ColumnIndex(_L("BinaryField")); while((err = stmt.Next()) == KSqlAtRow) { TPtrC8 data; TInt err = stmt.ColumnBinary(columnIndex, data); if(err == KErrNone) { <do something with the data>; } } if(err == KSqlAtEnd) <OK - no more records>; else <process the error>; stmt.Close();
CASE 3.4 - SELECT statements: large column data processing, where the data is accessed by the client using a stream:
RSqlDatabase database; ......... RSqlStatement stmt; TInt err = stmt.Prepare(database, _L("SELECT BinaryField FROM Tbl1")); TInt columnIndex = stmt.ColumnIndex(_L("BinaryField")); while((err = stmt.Next()) == KSqlAtRow) { RSqlColumnReadStream stream; err = stream.ColumnBinary(stmt, columnIndex); <do something with the data in the stream>; stream.Close(); } if(err == KSqlAtEnd) <OK - no more records>; else <process the error>; stmt.Close();
CASE 4 - the execution of a SQL statement with parameter(s), some of which may be large text or binary values:
RSqlDatabase database; ......... RSqlStatement stmt; TInt err = stmt.Prepare(database, _L("UPDATE Tbl1 SET LargeTextField = :LargeTextVal WHERE IdxField = :KeyVal")); TInt paramIndex1 = stmt.ParameterIndex(_L(":LargeTextVal")); TInt paramIndex2 = stmt.ParameterIndex(_L(":KeyVal")); for(TInt i=1;i<=10;++i) { RSqlParamWriteStream stream; err = stream.BindText(stmt, paramIndex1); <insert large text data into the stream>; stream.Close(); err = stmt.BindInt(paramIndex2, i); err = stmt.Exec(); stmt.Reset(); } stmt.Close();
The following table shows what is returned when the caller uses a specific column data retrieving function on a specific column type.
-------------------------------------------------------------------------------- Column type | ColumnInt() ColumnInt64() ColumnReal() ColumnText() ColumnBinary() -------------------------------------------------------------------------------- Null........|.0...........0.............0.0..........KNullDesC....KNullDesC8 Int.........|.Int.........Int64.........Real.........KNullDesC....KNullDesC8 Int64.......|.clamp.......Int64.........Real.........KNullDesC....KNullDesC8 Real........|.round.......round.........Real.........KNullDesC....KNullDesC8 Text........|.0...........0.............0.0..........Text.........KNullDesC8 Binary......|.0...........0.............0.0..........KNullDesC....Binary --------------------------------------------------------------------------------Note the following definitions:
"clamp": return KMinTInt or KMaxTInt if the value is outside the range that can be represented by the type returned by the accessor function.
"round": the floating point value will be rounded up to the nearest integer. If the result is outside the range that can be represented by the type returned by the accessor function, then it will be clamped.
Note that when handling blob and text data over 2Mb in size it is recommended that the RSqlBlobReadStream and RSqlBlobWriteStream classes or the TSqlBlob class is used instead. These classes provide a more RAM-efficient way of reading and writing large amounts of blob or text data from a database.
KMinTInt KMaxTInt KNullDesC KNullDesC8 RSqlBlobReadStream RSqlBlobWriteStream TSqlBlob
Private Member Functions | |
---|---|
CSqlStatementImpl & | Impl() |
Private Attributes | |
---|---|
CSqlStatementImpl * | iImpl |
IMPORT_C | RSqlStatement | ( | ) |
Initialises the pointer to the implementation object to NULL.
IMPORT_C TInt | BindInt64 | ( | TInt | aParameterIndex, |
TInt64 | aParameterValue | |||
) |
Sets the parameter to the specified 64-bit integer value.
The parameter is identified by the specified index value.
immediately after this SQL statement has been prepared
after a call to Reset()
IMPORT_C TInt | BindNull | ( | TInt | aParameterIndex | ) |
Sets the parameter to a NULL value.
The parameter is identified by the specified index value.
immediately after this SQL statement has been prepared
after a call to Reset()
TInt aParameterIndex | The index value identifying the parameter; this is 0 for the first parameter. |
IMPORT_C TInt | BindReal | ( | TInt | aParameterIndex, |
TReal | aParameterValue | |||
) |
Sets the parameter to the specified 64-bit floating point value.
The parameter is identified by the specified index value.
immediately after this SQL statement has been prepared
after a call to Reset()
IMPORT_C TInt | BindText | ( | TInt | aParameterIndex, |
const TDesC & | aParameterText | |||
) |
Sets the parameter to the specified 16-bit descriptor.
The parameter is identified by the specified index value.
immediately after this SQL statement has been prepared
after a call to Reset()
Note that when the text data to be bound is over 2Mb in size then use of the RSqlBlobWriteStream or TSqlBlob class should be considered instead.
These classes provide a more RAM-efficient way of writing large amounts of text data to a database, however no conversions are performed on the text data - it is simply stored as a stream of bytes. If the text data is part of a record to be inserted into a database then BindZeroBlob() should be called on the INSERT statement to create a placeholder for the text data, whose content can then be written using the above classes.
IMPORT_C TInt | BindZeroBlob | ( | TInt | aParameterIndex, |
TInt | aBlobSize | |||
) |
Binds a blob of length aBlobSize bytes that is filled with zeroes.
The parameter is identified by the specified index value.
immediately after this SQL statement has been prepared
after a call to Reset()
A zeroblob acts as a placeholder for a blob whose binary content is later written using the RSqlBlobWriteStream or TSqlBlob class.
Using zeroblobs provides a much more RAM-efficient way of creating large blobs than including the blob data in the INSERT statement and it is recommended for blobs that are over 2Mb in size.
Note that a zeroblob should be created in a column after which there are no columns that contain anything other than zeroblobs or NULLs, otherwise the zeroblob must be allocated in full in RAM and its benefit is lost.
When creating a zeroblob it is recommended, where possible, to create the zeroblob and then write the blob content (using the RSqlBlobWriteStream or TSqlBlob class) within the same transaction. Otherwise the zeroblob will have to be journalled before being written to.
IMPORT_C TPtrC8 | ColumnBinaryL | ( | TInt | aColumnIndex | ) | const |
Gets the value of the column as an 8-bit descriptor (leaves on failure).
The column is identified by the specified index value.
Note that the function can only be called after a successful call to Next(), i.e. after a call to Next() that has completed with a KSqlAtRow return code. Calling this function after an unsuccessful call to Next() raises a panic.
Note that when the binary data to be retrieved is over 2Mb in size then it is recommended that the RSqlBlobReadStream or TSqlBlob class is used instead. These classes provide a more RAM-efficient way of retrieving large amounts of binary data from a database.
TInt aColumnIndex | The index value identifying the column; this is 0 for the first column. |
IMPORT_C TInt | ColumnIndex | ( | const TDesC & | aColumnName | ) | const |
Gets the index (starting from 0) of the column with the given name.
The function does a case insensitive column name search.
This function can be called at any time after the SQL statement has been prepared.
const TDesC & aColumnName | The column name. |
IMPORT_C TInt64 | ColumnInt64 | ( | TInt | aColumnIndex | ) | const |
Gets the value of the column as a 64-bit integer.
The column is identified by the specified index value.
Note that the function can only be called after a successful call to Next(), i.e. after a call to Next() that has completed with a KSqlAtRow return code. Calling this function after an unsuccessful call to Next() raises a panic.
TInt aColumnIndex | The index value identifying the column; this is 0 for the first column. |
IMPORT_C TInt | ColumnName | ( | TInt | aColumnIndex, |
TPtrC & | aNameDest | |||
) |
Obtain the name of a column after preparing a query.
IMPORT_C TReal | ColumnReal | ( | TInt | aColumnIndex | ) | const |
Gets the value of the column as a 64-bit floating point value.
The column is identified by the specified index value.
Note that the function can only be called after a successful call to Next(), i.e. after a call to Next() that has completed with a KSqlAtRow return code. Calling this function after an unsuccessful call to Next() raises a panic.
TInt aColumnIndex | The index value identifying the column; this is 0 for the first column. |
IMPORT_C TPtrC | ColumnTextL | ( | TInt | aColumnIndex | ) | const |
Gets the value of the column as a 16-bit descriptor (leaves on failure).
The column is identified by the specified index value.
Note that the function can only be called after a successful call to Next(), i.e. after a call to Next() that has completed with a KSqlAtRow return code. Calling this function after an unsuccessful call to Next() raises a panic.
Note that when the text to be retrieved is over 2Mb in size then it is recommended that the RSqlBlobReadStream or TSqlBlob class is used instead. These classes provide a more RAM-efficient way of retrieving large amounts of text data from a database.
TInt aColumnIndex | The index value identifying the column; this is 0 for the first column. |
IMPORT_C TSqlColumnType | ColumnType | ( | TInt | aColumnIndex | ) | const |
Gets the runtime type of the column identified by the specified column index.
This function returns the actual runtime datatype of the specified column as opposed to its declared type.
Note that the function can only be called after a successful call to Next(), i.e. after a call to Next() that has completed with a KSqlAtRow return code. Calling this function after an unsuccessful call to Next() raises a panic.
TInt aColumnIndex | The index value identifying the column; this is 0 for the first column. |
IMPORT_C TInt | DeclaredColumnType | ( | TInt | aColumnIndex, |
TSqlColumnType & | aColumnType | |||
) | const |
Gets the declared type of the column identified by the specified column index.
Note that the function can only be called when executing a SELECT query, and only after a successful call to Prepare().
This function returns the datatype that the specified column was originally declared to have.
- if the column type name contains the string "INT", then the declared column type is ESqlInt; - if the column type name contains any of the strings "CHAR, "TEXT" or "CLOB", then the declared column type is ESqlText; - if the column type name contains any of the strings "BLOB" or "BINARY", then the declared column type is ESqlBinary; - if the column type name contains any of the strings "FLOAT", "REAL" or "DOUBLE", then the declared column type is ESqlReal; - in all other cases the declared column type is assumed to be ESqlInt;
TInt aColumnIndex | The index value identifying the column. This is 0 for the first column. |
TSqlColumnType & aColumnType | Output parameter. If the call completes successfully, aColumnType contains the type of the column, one of TSqlColumnType enum item values. |
CSqlStatementImpl & | Impl | ( | ) | const [private] |
Returns a reference to the implementation object of RSqlStatement - CSqlStatementImpl.
IMPORT_C TBool | IsNull | ( | TInt | aColumnIndex | ) | const |
Tests whether the value of the specified column is NULL.
The column is identified by the specified index value.
Note that the function can only be called after a successful call to Next(), i.e. after a call to Next() that has completed with a KSqlAtRow return code. Calling this function after an unsuccessful call to Next() raises a panic.
TInt aColumnIndex | The index value identifying the column; this is 0 for the first column. |
IMPORT_C TInt | Next | ( | ) |
Retrieves a record.
If the prepared SQL statement is a "SELECT" statement, and is expected to return a set of records, then this function can be used to retrieve that record data.
If the SQL statement contains parameters, then their values must be bound before this function is called.
If the call to this function completes successfully, i.e. it returns with KSqlAtRow, then this RSqlStatement object contains the record data, and this data will remain valid for access until another call is made to any RSqlStatement function.
Note that if this call to Next() fails, as indicated by a return code value other than KSqlAtRow, then calls to these RSqlStatement::Column...() functions will raise a panic.
IMPORT_C TInt | ParamName | ( | TInt | aParameterIndex, |
TPtrC & | aNameDest | |||
) |
Obtain the name of a parameter after preparing a DML query. The parameter names are returned in exactly the same form as supplied in SQL statement. For example, if the parameter name is ":Prm", then the ":" prefix will not be omitted.
ParamName has the same behaviour as ParameterName. It is provided to maintain source compatibility with previous Symbian releases.
This function can be called at any time after the DML SQL statement has been prepared.
IMPORT_C TInt | ParameterIndex | ( | const TDesC & | aParameterName | ) | const |
Gets the index (starting from 0) of the parameter with the given name.
The function does a case insensitive parameter name search.
For example, if the parameter name is ":Prm", then the ":" prefix cannot be omitted when you call ParameterIndex().
This function can be called at any time after the SQL statement has been prepared.
const TDesC & aParameterName | The parameter name. |
IMPORT_C TInt | ParameterName | ( | TInt | aParameterIndex, |
TPtrC & | aNameDest | |||
) |
Obtain the name of a parameter after preparing a DML query. The parameter names are returned in exactly the same form as supplied in SQL statement. For example, if the parameter name is ":Prm", then the ":" prefix will not be omitted.
This function can be called at any time after the DML SQL statement has been prepared.
IMPORT_C TInt | Prepare | ( | RSqlDatabase & | aDatabase, |
const TDesC & | aSqlStmt | |||
) |
RSqlDatabase & aDatabase | |
const TDesC & aSqlStmt |
IMPORT_C void | PrepareL | ( | RSqlDatabase & | aDatabase, |
const TDesC & | aSqlStmt | |||
) |
Prepares the supplied 16-bit SQL statement for execution.
An RSqlStatement object can prepare and execute a parameterised SQL statement or an SQL statement without parameters.
The function can only deal with one SQL statement at a time, i.e. if you supply more than one SQL statement, each separated by a ";" character, then the function returns an error.
Note that when the statement is to be used to retrieve or write blob or text data that is over 2Mb in size then it is recommended that the RSqlBlobReadStream and RSqlBlobWriteStream classes or the TSqlBlob class is used instead. These classes provide a more RAM-efficient way of reading and writing large amounts of blob or text data from a database.
RSqlDatabase & aDatabase | A reference to the RSqlDatabase object that represents the database for which the SQL statement is being prepared. |
const TDesC & aSqlStmt | A string of 16-bit wide characters containing the SQL statement to be prepared. |
IMPORT_C void | PrepareL | ( | RSqlDatabase & | aDatabase, |
const TDesC8 & | aSqlStmt | |||
) |
RSqlDatabase & aDatabase | |
const TDesC8 & aSqlStmt |
IMPORT_C TInt | Reset | ( | ) |
Resets the prepared SQL statement to its initial state and makes it ready to be executed again.
Any SQL statement parameters that had values bound to them, retain their values.
If this object processes a parameterised SQL statement, then the parameter values can be bound after the call to Reset().
If the call to this function fails because of a database-specific type error (i.e. the error is categorised as of type ESqlDbError), then a textual description of the error can be obtained calling RSqlDatabase::LastErrorMessage().
Usage pattern 1:
RSqlStatement stmt; TInt err = stmt.Prepare(<database>, <SQL statement>); while(<condition>) { err = stmt.Bind<parameter type>(<parameter index>, <value>); ... err = stmt.Exec(); .... err = stmt.Reset(); } stmt.Close();
Usage pattern 2:
RSqlStatement stmt; TInt err = stmt.Prepare(<database>, <SQL statement>); while(<condition>) { err = stmt.Bind<parameter type>(<parameter index>, <value>); ... while((err = stmt.Next()) == KSqlAtRow) { .... } err = stmt.Reset(); } stmt.Close();
Copyright ©2010 Nokia Corporation and/or its subsidiary(-ies).
All rights
reserved. Unless otherwise stated, these materials are provided under the terms of the Eclipse Public License
v1.0.