зеркало из https://github.com/microsoft/msphpsql.git
Simplified parse_param_array in sqlsrv (#1262)
This commit is contained in:
Родитель
0da75f5b92
Коммит
b49cb5106f
|
@ -96,13 +96,14 @@ sqlsrv_phptype determine_sqlsrv_php_type( sqlsrv_stmt const* stmt, SQLINTEGER sq
|
|||
void determine_stmt_has_rows( _Inout_ ss_sqlsrv_stmt* stmt );
|
||||
bool is_valid_sqlsrv_phptype( _In_ sqlsrv_phptype type );
|
||||
bool is_valid_sqlsrv_sqltype( _In_ sqlsrv_sqltype type );
|
||||
void parse_param_array( _Inout_ ss_sqlsrv_stmt* stmt, _Inout_ zval* param_array, zend_ulong index, _Out_ SQLSMALLINT& direction,
|
||||
_Out_ SQLSRV_PHPTYPE& php_out_type, _Out_ SQLSRV_ENCODING& encoding, _Out_ SQLSMALLINT& sql_type,
|
||||
_Out_ SQLULEN& column_size, _Out_ SQLSMALLINT& decimal_digits );
|
||||
void type_and_encoding( INTERNAL_FUNCTION_PARAMETERS, _In_ int type );
|
||||
void type_and_size_calc( INTERNAL_FUNCTION_PARAMETERS, _In_ int type );
|
||||
void type_and_precision_calc( INTERNAL_FUNCTION_PARAMETERS, _In_ int type );
|
||||
bool verify_and_set_encoding( _In_ const char* encoding_string, _Inout_ sqlsrv_phptype& phptype_encoding );
|
||||
zval* parse_param_array(_Inout_ ss_sqlsrv_stmt* stmt, _Inout_ HashTable* param_ht, zend_ulong index,
|
||||
_Out_ SQLSMALLINT& direction, _Out_ SQLSRV_PHPTYPE& php_out_type,
|
||||
_Out_ SQLSRV_ENCODING& encoding, _Out_ SQLSMALLINT& sql_type,
|
||||
_Out_ SQLULEN& column_size, _Out_ SQLSMALLINT& decimal_digits);
|
||||
|
||||
}
|
||||
|
||||
|
@ -1194,44 +1195,50 @@ void bind_params( _Inout_ ss_sqlsrv_stmt* stmt )
|
|||
|
||||
HashTable* params_ht = Z_ARRVAL_P( params_z );
|
||||
|
||||
zend_ulong index = -1;
|
||||
zend_string *key = NULL;
|
||||
zval* param_z = NULL;
|
||||
zend_ulong index = -1;
|
||||
zend_string *key = NULL;
|
||||
zval* param_z = NULL;
|
||||
|
||||
ZEND_HASH_FOREACH_KEY_VAL( params_ht, index, key, param_z ) {
|
||||
zval* value_z = NULL;
|
||||
SQLSMALLINT direction = SQL_PARAM_INPUT;
|
||||
SQLSRV_ENCODING encoding = stmt->encoding();
|
||||
if( stmt->encoding() == SQLSRV_ENCODING_DEFAULT ) {
|
||||
encoding = stmt->conn->encoding();
|
||||
}
|
||||
SQLSMALLINT sql_type = SQL_UNKNOWN_TYPE;
|
||||
SQLULEN column_size = SQLSRV_UNKNOWN_SIZE;
|
||||
SQLSMALLINT decimal_digits = 0;
|
||||
SQLSRV_PHPTYPE php_out_type = SQLSRV_PHPTYPE_INVALID;
|
||||
ZEND_HASH_FOREACH_KEY_VAL( params_ht, index, key, param_z ) {
|
||||
// make sure it's an integer index
|
||||
int type = key ? HASH_KEY_IS_STRING : HASH_KEY_IS_LONG;
|
||||
CHECK_CUSTOM_ERROR(type != HASH_KEY_IS_LONG, stmt, SS_SQLSRV_ERROR_PARAM_INVALID_INDEX) {
|
||||
throw ss::SSException();
|
||||
}
|
||||
|
||||
// make sure it's an integer index
|
||||
int type = key ? HASH_KEY_IS_STRING : HASH_KEY_IS_LONG;
|
||||
CHECK_CUSTOM_ERROR( type != HASH_KEY_IS_LONG, stmt, SS_SQLSRV_ERROR_PARAM_INVALID_INDEX ) {
|
||||
throw ss::SSException();
|
||||
}
|
||||
zval* value_z = NULL;
|
||||
SQLSMALLINT direction = SQL_PARAM_INPUT;
|
||||
SQLSRV_ENCODING encoding = stmt->encoding();
|
||||
if( stmt->encoding() == SQLSRV_ENCODING_DEFAULT ) {
|
||||
encoding = stmt->conn->encoding();
|
||||
}
|
||||
SQLSMALLINT sql_type = SQL_UNKNOWN_TYPE;
|
||||
SQLULEN column_size = SQLSRV_UNKNOWN_SIZE;
|
||||
SQLSMALLINT decimal_digits = 0;
|
||||
SQLSRV_PHPTYPE php_out_type = SQLSRV_PHPTYPE_INVALID;
|
||||
|
||||
// if it's a parameter array
|
||||
if( Z_TYPE_P( param_z ) == IS_ARRAY ) {
|
||||
|
||||
zval* var = NULL;
|
||||
int zr = ( NULL != ( var = zend_hash_index_find( Z_ARRVAL_P( param_z ), 0 ))) ? SUCCESS : FAILURE;
|
||||
CHECK_CUSTOM_ERROR( zr == FAILURE, stmt, SS_SQLSRV_ERROR_VAR_REQUIRED, index + 1 ) {
|
||||
throw ss::SSException();
|
||||
if (Z_TYPE_P(param_z) == IS_ARRAY) {
|
||||
try {
|
||||
HashTable* param_ht = Z_ARRVAL_P(param_z);
|
||||
// Check the number of elements in the array
|
||||
int num_elems = zend_hash_num_elements(param_ht);
|
||||
if (num_elems > 1) {
|
||||
value_z = parse_param_array(stmt, param_ht, index, direction, php_out_type, encoding, sql_type, column_size, decimal_digits);
|
||||
} else {
|
||||
// Simply get the first variable and use the defaults
|
||||
value_z = zend_hash_index_find(param_ht, 0);
|
||||
if (value_z == NULL) {
|
||||
THROW_SS_ERROR(stmt, SS_SQLSRV_ERROR_VAR_REQUIRED, index + 1);
|
||||
}
|
||||
}
|
||||
} catch (core::CoreException&) {
|
||||
SQLFreeStmt(stmt->handle(), SQL_RESET_PARAMS);
|
||||
throw;
|
||||
}
|
||||
|
||||
// parse the parameter array that the user gave
|
||||
parse_param_array( stmt, param_z, index, direction, php_out_type, encoding, sql_type, column_size,
|
||||
decimal_digits );
|
||||
value_z = var;
|
||||
}
|
||||
else {
|
||||
CHECK_CUSTOM_ERROR( !stmt->prepared && stmt->conn->ce_option.enabled, stmt, SS_SQLSRV_ERROR_AE_QUERY_SQLTYPE_REQUIRED ) {
|
||||
CHECK_CUSTOM_ERROR(!stmt->prepared && stmt->conn->ce_option.enabled, stmt, SS_SQLSRV_ERROR_AE_QUERY_SQLTYPE_REQUIRED) {
|
||||
throw ss::SSException();
|
||||
}
|
||||
value_z = param_z;
|
||||
|
@ -1252,7 +1259,6 @@ void bind_params( _Inout_ ss_sqlsrv_stmt* stmt )
|
|||
}
|
||||
|
||||
// bind the parameter
|
||||
SQLSRV_ASSERT( value_z != NULL, "bind_params: value_z is null." );
|
||||
core_sqlsrv_bind_param( stmt, static_cast<SQLUSMALLINT>( index ), direction, value_z, php_out_type, encoding, sql_type, column_size,
|
||||
decimal_digits );
|
||||
|
||||
|
@ -1724,6 +1730,7 @@ sqlsrv_phptype determine_sqlsrv_php_type( _In_ ss_sqlsrv_stmt const* stmt, _In_
|
|||
break;
|
||||
default:
|
||||
sqlsrv_phptype.typeinfo.type = PHPTYPE_INVALID;
|
||||
SQLSRV_ASSERT(false, "An invalid php type was returned with (supposedly) validated sql type and column_size");
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -1905,179 +1912,106 @@ void fetch_fields_common( _Inout_ ss_sqlsrv_stmt* stmt, _In_ zend_long fetch_typ
|
|||
|
||||
}
|
||||
|
||||
void parse_param_array( _Inout_ ss_sqlsrv_stmt* stmt, _Inout_ zval* param_array, zend_ulong index, _Out_ SQLSMALLINT& direction,
|
||||
zval* parse_param_array(_Inout_ ss_sqlsrv_stmt* stmt, _Inout_ HashTable* param_ht, zend_ulong index, _Out_ SQLSMALLINT& direction,
|
||||
_Out_ SQLSRV_PHPTYPE& php_out_type, _Out_ SQLSRV_ENCODING& encoding, _Out_ SQLSMALLINT& sql_type,
|
||||
_Out_ SQLULEN& column_size, _Out_ SQLSMALLINT& decimal_digits )
|
||||
_Out_ SQLULEN& column_size, _Out_ SQLSMALLINT& decimal_digits)
|
||||
{
|
||||
zval* var_or_val = NULL;
|
||||
zval* temp = NULL;
|
||||
HashTable* param_ht = Z_ARRVAL_P( param_array );
|
||||
sqlsrv_sqltype sqlsrv_sql_type;
|
||||
HashPosition pos;
|
||||
zval* var_or_val = zend_hash_index_find(param_ht, 0);
|
||||
bool php_type_param_is_null = true;
|
||||
bool sql_type_param_is_null = true;
|
||||
|
||||
try {
|
||||
// Assumption: there are more than only the variable, parse the rest of the array
|
||||
zval* dir = zend_hash_index_find(param_ht, 1);
|
||||
if (Z_TYPE_P(dir) != IS_NULL) {
|
||||
// if param direction is specified, make sure it's valid
|
||||
CHECK_CUSTOM_ERROR(Z_TYPE_P(dir) != IS_LONG, stmt, SS_SQLSRV_ERROR_INVALID_PARAMETER_DIRECTION, index + 1) {
|
||||
throw ss::SSException();
|
||||
}
|
||||
direction = static_cast<SQLSMALLINT>(Z_LVAL_P(dir));
|
||||
|
||||
bool php_type_param_was_null = true;
|
||||
bool sql_type_param_was_null = true;
|
||||
|
||||
php_out_type = SQLSRV_PHPTYPE_INVALID;
|
||||
encoding = SQLSRV_ENCODING_INVALID;
|
||||
|
||||
// handle the array parameters that contain the value/var, direction, php_type, sql_type
|
||||
zend_hash_internal_pointer_reset_ex( param_ht, &pos );
|
||||
if( zend_hash_has_more_elements_ex( param_ht, &pos ) == FAILURE ||
|
||||
(var_or_val = zend_hash_get_current_data_ex(param_ht, &pos)) == NULL) {
|
||||
|
||||
THROW_SS_ERROR( stmt, SS_SQLSRV_ERROR_VAR_REQUIRED, index + 1 );
|
||||
CHECK_CUSTOM_ERROR(direction != SQL_PARAM_INPUT && direction != SQL_PARAM_OUTPUT && direction != SQL_PARAM_INPUT_OUTPUT,
|
||||
stmt, SS_SQLSRV_ERROR_INVALID_PARAMETER_DIRECTION, index + 1) {
|
||||
throw ss::SSException();
|
||||
}
|
||||
CHECK_CUSTOM_ERROR(direction != SQL_PARAM_INPUT && !Z_ISREF_P(var_or_val), stmt, SS_SQLSRV_ERROR_PARAM_VAR_NOT_REF, index + 1) {
|
||||
throw ss::SSException();
|
||||
}
|
||||
}
|
||||
|
||||
// if the direction is included, then use what they gave, otherwise INPUT is assumed
|
||||
if ( zend_hash_move_forward_ex( param_ht, &pos ) == SUCCESS && ( temp = zend_hash_get_current_data_ex( param_ht, &pos )) != NULL &&
|
||||
Z_TYPE_P( temp ) != IS_NULL ) {
|
||||
// Check if the user provides php type or sql type or both
|
||||
zval* phptype_z = zend_hash_index_find(param_ht, 2);
|
||||
zval* sqltype_z = zend_hash_index_find(param_ht, 3);
|
||||
|
||||
CHECK_CUSTOM_ERROR( Z_TYPE_P( temp ) != IS_LONG, stmt, SS_SQLSRV_ERROR_INVALID_PARAMETER_DIRECTION, index + 1 ) {
|
||||
php_type_param_is_null = (phptype_z == NULL || Z_TYPE_P(phptype_z) == IS_NULL);
|
||||
sql_type_param_is_null = (sqltype_z == NULL || Z_TYPE_P(sqltype_z) == IS_NULL);
|
||||
|
||||
throw ss::SSException();
|
||||
if (php_type_param_is_null) {
|
||||
// so set default for php type based on the variable
|
||||
if (Z_ISREF_P(var_or_val)) {
|
||||
php_out_type = zend_to_sqlsrv_phptype[Z_TYPE_P(Z_REFVAL_P(var_or_val))];
|
||||
} else {
|
||||
php_out_type = zend_to_sqlsrv_phptype[Z_TYPE_P(var_or_val)];
|
||||
}
|
||||
direction = static_cast<SQLSMALLINT>( Z_LVAL_P( temp ));
|
||||
CHECK_CUSTOM_ERROR( direction != SQL_PARAM_INPUT && direction != SQL_PARAM_OUTPUT && direction != SQL_PARAM_INPUT_OUTPUT,
|
||||
stmt, SS_SQLSRV_ERROR_INVALID_PARAMETER_DIRECTION, index + 1 ) {
|
||||
} else {
|
||||
CHECK_CUSTOM_ERROR(Z_TYPE_P(phptype_z) != IS_LONG, stmt, SQLSRV_ERROR_INVALID_PARAMETER_PHPTYPE, index + 1) {
|
||||
throw ss::SSException();
|
||||
}
|
||||
|
||||
CHECK_CUSTOM_ERROR( !Z_ISREF_P( var_or_val ) && ( direction == SQL_PARAM_OUTPUT || direction == SQL_PARAM_INPUT_OUTPUT ), stmt, SS_SQLSRV_ERROR_PARAM_VAR_NOT_REF, index + 1 ) {
|
||||
sqlsrv_phptype srv_phptype;
|
||||
srv_phptype.value = Z_LVAL_P(phptype_z);
|
||||
CHECK_CUSTOM_ERROR(!is_valid_sqlsrv_phptype(srv_phptype), stmt, SQLSRV_ERROR_INVALID_PARAMETER_PHPTYPE, index + 1) {
|
||||
throw ss::SSException();
|
||||
}
|
||||
|
||||
}
|
||||
else {
|
||||
direction = SQL_PARAM_INPUT;
|
||||
}
|
||||
|
||||
// extract the php type and encoding from the 3rd parameter
|
||||
if ( zend_hash_move_forward_ex( param_ht, &pos ) == SUCCESS && ( temp = zend_hash_get_current_data_ex( param_ht, &pos )) != NULL &&
|
||||
Z_TYPE_P( temp ) != IS_NULL ) {
|
||||
|
||||
php_type_param_was_null = false;
|
||||
sqlsrv_phptype sqlsrv_phptype;
|
||||
|
||||
CHECK_CUSTOM_ERROR( Z_TYPE_P( temp ) != IS_LONG, stmt, SQLSRV_ERROR_INVALID_PARAMETER_PHPTYPE, index + 1 ) {
|
||||
|
||||
throw ss::SSException();
|
||||
}
|
||||
|
||||
sqlsrv_phptype.value = Z_LVAL_P( temp );
|
||||
|
||||
CHECK_CUSTOM_ERROR( !is_valid_sqlsrv_phptype( sqlsrv_phptype ), stmt, SQLSRV_ERROR_INVALID_PARAMETER_PHPTYPE,
|
||||
index + 1 ) {
|
||||
|
||||
throw ss::SSException();
|
||||
}
|
||||
|
||||
php_out_type = static_cast<SQLSRV_PHPTYPE>( sqlsrv_phptype.typeinfo.type );
|
||||
encoding = ( SQLSRV_ENCODING ) sqlsrv_phptype.typeinfo.encoding;
|
||||
php_out_type = static_cast<SQLSRV_PHPTYPE>(srv_phptype.typeinfo.type);
|
||||
encoding = (SQLSRV_ENCODING)srv_phptype.typeinfo.encoding;
|
||||
// if the call has a SQLSRV_PHPTYPE_STRING/STREAM('default'), then the stream is in the encoding established
|
||||
// by the connection
|
||||
if( encoding == SQLSRV_ENCODING_DEFAULT ) {
|
||||
encoding = stmt->conn->encoding();
|
||||
}
|
||||
}
|
||||
// set default for php type and encoding if not supplied
|
||||
else {
|
||||
|
||||
php_type_param_was_null = true;
|
||||
|
||||
if ( Z_ISREF_P( var_or_val )){
|
||||
php_out_type = zend_to_sqlsrv_phptype[Z_TYPE_P( Z_REFVAL_P( var_or_val ))];
|
||||
}
|
||||
else{
|
||||
php_out_type = zend_to_sqlsrv_phptype[Z_TYPE_P( var_or_val )];
|
||||
}
|
||||
encoding = stmt->encoding();
|
||||
if( encoding == SQLSRV_ENCODING_DEFAULT ) {
|
||||
if (encoding == SQLSRV_ENCODING_DEFAULT) {
|
||||
encoding = stmt->conn->encoding();
|
||||
}
|
||||
}
|
||||
|
||||
// get the server type, column size/precision and the decimal digits if provided
|
||||
if ( zend_hash_move_forward_ex( param_ht, &pos ) == SUCCESS && ( temp = zend_hash_get_current_data_ex( param_ht, &pos )) != NULL &&
|
||||
Z_TYPE_P( temp ) != IS_NULL ) {
|
||||
|
||||
sql_type_param_was_null = false;
|
||||
|
||||
CHECK_CUSTOM_ERROR( Z_TYPE_P( temp ) != IS_LONG, stmt, SQLSRV_ERROR_INVALID_PARAMETER_SQLTYPE, index + 1 ) {
|
||||
|
||||
if (sql_type_param_is_null) {
|
||||
// the sql type is not specified, which is required for always encrypted for non-prepared statements
|
||||
CHECK_CUSTOM_ERROR(stmt->conn->ce_option.enabled && !stmt->prepared, stmt, SS_SQLSRV_ERROR_AE_QUERY_SQLTYPE_REQUIRED) {
|
||||
throw ss::SSException();
|
||||
}
|
||||
} else {
|
||||
CHECK_CUSTOM_ERROR(Z_TYPE_P(sqltype_z) != IS_LONG, stmt, SQLSRV_ERROR_INVALID_PARAMETER_SQLTYPE, index + 1) {
|
||||
throw ss::SSException();
|
||||
}
|
||||
|
||||
sqlsrv_sql_type.value = Z_LVAL_P( temp );
|
||||
|
||||
// since the user supplied this type, make sure it's valid
|
||||
CHECK_CUSTOM_ERROR( !is_valid_sqlsrv_sqltype( sqlsrv_sql_type ), stmt, SQLSRV_ERROR_INVALID_PARAMETER_SQLTYPE,
|
||||
index + 1 ) {
|
||||
|
||||
sqlsrv_sqltype sqlsrv_sql_type;
|
||||
sqlsrv_sql_type.value = Z_LVAL_P(sqltype_z);
|
||||
CHECK_CUSTOM_ERROR(!is_valid_sqlsrv_sqltype(sqlsrv_sql_type), stmt, SQLSRV_ERROR_INVALID_PARAMETER_SQLTYPE, index + 1) {
|
||||
throw ss::SSException();
|
||||
}
|
||||
|
||||
bool size_okay = determine_column_size_or_precision( stmt, sqlsrv_sql_type, &column_size, &decimal_digits );
|
||||
|
||||
CHECK_CUSTOM_ERROR( !size_okay, stmt, SS_SQLSRV_ERROR_INVALID_PARAMETER_PRECISION, index + 1 ) {
|
||||
|
||||
bool size_okay = determine_column_size_or_precision(stmt, sqlsrv_sql_type, &column_size, &decimal_digits);
|
||||
CHECK_CUSTOM_ERROR(!size_okay, stmt, SS_SQLSRV_ERROR_INVALID_PARAMETER_PRECISION, index + 1) {
|
||||
throw ss::SSException();
|
||||
}
|
||||
|
||||
sql_type = sqlsrv_sql_type.typeinfo.type;
|
||||
}
|
||||
// else the sql type and size are unknown, so tell the core layer to use its defaults
|
||||
else {
|
||||
CHECK_CUSTOM_ERROR( !stmt->prepared && stmt->conn->ce_option.enabled, stmt, SS_SQLSRV_ERROR_AE_QUERY_SQLTYPE_REQUIRED ) {
|
||||
throw ss::SSException();
|
||||
|
||||
if (direction != SQL_PARAM_INPUT && php_type_param_is_null) {
|
||||
sqlsrv_phptype srv_phptype;
|
||||
srv_phptype = determine_sqlsrv_php_type(stmt, sql_type, (SQLUINTEGER)column_size, true);
|
||||
|
||||
php_out_type = static_cast<SQLSRV_PHPTYPE>(srv_phptype.typeinfo.type);
|
||||
encoding = static_cast<SQLSRV_ENCODING>(srv_phptype.typeinfo.encoding);
|
||||
}
|
||||
sql_type_param_was_null = true;
|
||||
|
||||
sql_type = SQL_UNKNOWN_TYPE;
|
||||
column_size = SQLSRV_UNKNOWN_SIZE;
|
||||
decimal_digits = 0;
|
||||
}
|
||||
|
||||
// if the user for some reason provides an inout / output parameter with a null phptype and a specified
|
||||
// sql server type, infer the php type from the sql server type.
|
||||
if( direction != SQL_PARAM_INPUT && php_type_param_was_null && !sql_type_param_was_null ) {
|
||||
|
||||
sqlsrv_phptype sqlsrv_phptype;
|
||||
|
||||
sqlsrv_phptype = determine_sqlsrv_php_type( stmt, sql_type, (SQLUINTEGER)column_size, true );
|
||||
|
||||
// we DIE here since everything should have been validated already and to return the user an error
|
||||
// for our own logic error would be confusing/misleading.
|
||||
SQLSRV_ASSERT( sqlsrv_phptype.typeinfo.type != PHPTYPE_INVALID, "An invalid php type was returned with (supposed) "
|
||||
"validated sql type and column_size" );
|
||||
|
||||
php_out_type = static_cast<SQLSRV_PHPTYPE>( sqlsrv_phptype.typeinfo.type );
|
||||
encoding = static_cast<SQLSRV_ENCODING>( sqlsrv_phptype.typeinfo.encoding );
|
||||
}
|
||||
|
||||
// verify that the parameter is a valid output param type
|
||||
if( direction == SQL_PARAM_OUTPUT ) {
|
||||
|
||||
switch( php_out_type ) {
|
||||
case SQLSRV_PHPTYPE_NULL:
|
||||
case SQLSRV_PHPTYPE_DATETIME:
|
||||
case SQLSRV_PHPTYPE_STREAM:
|
||||
THROW_CORE_ERROR( stmt, SS_SQLSRV_ERROR_INVALID_OUTPUT_PARAM_TYPE );
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
if (direction == SQL_PARAM_OUTPUT) {
|
||||
if (php_out_type == SQLSRV_PHPTYPE_NULL || php_out_type == SQLSRV_PHPTYPE_DATETIME || php_out_type == SQLSRV_PHPTYPE_STREAM) {
|
||||
THROW_CORE_ERROR(stmt, SS_SQLSRV_ERROR_INVALID_OUTPUT_PARAM_TYPE);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
catch( core::CoreException& ) {
|
||||
|
||||
SQLFreeStmt( stmt->handle(), SQL_RESET_PARAMS );
|
||||
throw;
|
||||
}
|
||||
return var_or_val;
|
||||
}
|
||||
|
||||
bool is_valid_sqlsrv_phptype( _In_ sqlsrv_phptype type )
|
||||
|
|
|
@ -9,28 +9,45 @@ PHPT_EXEC=true
|
|||
require_once('MsSetup.inc');
|
||||
require_once('MsCommon_mid-refactor.inc');
|
||||
|
||||
function cleanup($conn, $schema)
|
||||
function cleanup($conn, $schema, $pre2016)
|
||||
{
|
||||
global $dropSchema;
|
||||
|
||||
$dropProcedure = dropProcSQL($conn, "[$schema].[AddReview]");
|
||||
$conn->exec($dropProcedure);
|
||||
if ($pre2016) {
|
||||
// ignore the errors dropping all these
|
||||
$conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_SILENT);
|
||||
|
||||
$conn->exec("DROP PROCEDURE [$schema].[AddReview]");
|
||||
$conn->exec("DROP TYPE [$schema].[TestTVP3]");
|
||||
$conn->exec("DROP TYPE [$schema].[SupplierType]");
|
||||
$conn->exec("DROP SCHEMA [$schema]");
|
||||
|
||||
$conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
|
||||
} else {
|
||||
global $dropSchema;
|
||||
|
||||
$dropProcedure = dropProcSQL($conn, "[$schema].[AddReview]");
|
||||
$conn->exec($dropProcedure);
|
||||
|
||||
$dropTableType = dropTableTypeSQL($conn, "TestTVP3", $schema);
|
||||
$conn->exec($dropTableType);
|
||||
$dropTableType = dropTableTypeSQL($conn, "SupplierType", $schema);
|
||||
$conn->exec($dropTableType);
|
||||
$dropTableType = dropTableTypeSQL($conn, "TestTVP3", $schema);
|
||||
$conn->exec($dropTableType);
|
||||
$dropTableType = dropTableTypeSQL($conn, "SupplierType", $schema);
|
||||
$conn->exec($dropTableType);
|
||||
|
||||
$conn->exec($dropSchema);
|
||||
$conn->exec($dropSchema);
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
$conn = new PDO("sqlsrv:server = $server; database=$databaseName;", $uid, $pwd);
|
||||
$conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
|
||||
|
||||
$stmt = $conn->query("SELECT @@VERSION");
|
||||
$result = $stmt->fetch(PDO::FETCH_NUM)[0];
|
||||
$version = explode(' ', $result);
|
||||
$pre2016 = ($version[3] < '2016');
|
||||
|
||||
// Use a different schema instead of dbo
|
||||
$schema = 'Sales DB';
|
||||
cleanup($conn, $schema);
|
||||
cleanup($conn, $schema, $pre2016);
|
||||
|
||||
// Create the table type and stored procedure
|
||||
$conn->exec($createSchema);
|
||||
|
@ -85,7 +102,7 @@ try {
|
|||
fclose($image);
|
||||
unset($stmt);
|
||||
|
||||
cleanup($conn, $schema);
|
||||
cleanup($conn, $schema, $pre2016);
|
||||
|
||||
unset($conn);
|
||||
echo "Done" . PHP_EOL;
|
||||
|
|
|
@ -28,29 +28,45 @@ function invokeProc($conn, $proc, $tvpInput, $caseNo, $inputParam = true)
|
|||
}
|
||||
}
|
||||
|
||||
function cleanup($conn, $schema, $tvpType, $procName)
|
||||
function cleanup($conn, $schema, $tvpType, $procName, $pre2016)
|
||||
{
|
||||
global $dropSchema;
|
||||
|
||||
$dropProcedure = dropProcSQL($conn, "[$schema].[$procName]");
|
||||
$conn->exec($dropProcedure);
|
||||
if ($pre2016) {
|
||||
// ignore the errors dropping all these
|
||||
$conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_SILENT);
|
||||
|
||||
$conn->exec("DROP PROCEDURE [$schema].[$procName]");
|
||||
$conn->exec("DROP TYPE [$schema].[$tvpType]");
|
||||
$conn->exec("DROP SCHEMA [$schema]");
|
||||
|
||||
$conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
|
||||
} else {
|
||||
global $dropSchema;
|
||||
|
||||
$dropProcedure = dropProcSQL($conn, "[$schema].[$procName]");
|
||||
$conn->exec($dropProcedure);
|
||||
|
||||
$dropTableType = dropTableTypeSQL($conn, $tvpType, $schema);
|
||||
$conn->exec($dropTableType);
|
||||
|
||||
$conn->exec($dropSchema);
|
||||
$dropTableType = dropTableTypeSQL($conn, $tvpType, $schema);
|
||||
$conn->exec($dropTableType);
|
||||
|
||||
$conn->exec($dropSchema);
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
$conn = new PDO("sqlsrv:server = $server; database=$databaseName;", $uid, $pwd);
|
||||
$conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
|
||||
|
||||
$stmt = $conn->query("SELECT @@VERSION");
|
||||
$result = $stmt->fetch(PDO::FETCH_NUM)[0];
|
||||
$version = explode(' ', $result);
|
||||
$pre2016 = ($version[3] < '2016');
|
||||
|
||||
// Use a different schema instead of dbo
|
||||
$schema = 'Sales DB';
|
||||
$tvpType = 'TestTVP3';
|
||||
$procName = 'SelectTVP3';
|
||||
|
||||
cleanup($conn, $schema, $tvpType, $procName);
|
||||
cleanup($conn, $schema, $tvpType, $procName, $pre2016);
|
||||
|
||||
// Create the table type and stored procedure
|
||||
$conn->exec($createSchema);
|
||||
|
@ -162,7 +178,7 @@ try {
|
|||
$tvpInput = array($tvpTypeName => $inputs);
|
||||
invokeProc($conn, $callSelectTVP3, $tvpInput, 14);
|
||||
|
||||
cleanup($conn, $schema, $tvpType, $procName);
|
||||
cleanup($conn, $schema, $tvpType, $procName, $pre2016);
|
||||
|
||||
unset($conn);
|
||||
echo "Done" . PHP_EOL;
|
||||
|
|
|
@ -10,28 +10,42 @@ require_once('MsCommon.inc');
|
|||
|
||||
date_default_timezone_set('America/Los_Angeles');
|
||||
|
||||
function cleanup($conn, $schema)
|
||||
function cleanup($conn, $schema, $pre2016)
|
||||
{
|
||||
global $dropSchema;
|
||||
|
||||
$dropProcedure = dropProcSQL($conn, "[$schema].[AddReview]");
|
||||
sqlsrv_query($conn, $dropProcedure);
|
||||
if ($pre2016) {
|
||||
sqlsrv_query($conn, "DROP PROCEDURE [$schema].[AddReview]");
|
||||
sqlsrv_query($conn, "DROP TYPE [$schema].[TestTVP3]");
|
||||
sqlsrv_query($conn, "DROP TYPE [$schema].[SupplierType]");
|
||||
sqlsrv_query($conn, "DROP SCHEMA [$schema]");
|
||||
} else {
|
||||
global $dropSchema;
|
||||
|
||||
$dropProcedure = dropProcSQL($conn, "[$schema].[AddReview]");
|
||||
sqlsrv_query($conn, $dropProcedure);
|
||||
|
||||
$dropTableType = dropTableTypeSQL($conn, "TestTVP3", $schema);
|
||||
sqlsrv_query($conn, $dropTableType);
|
||||
$dropTableType = dropTableTypeSQL($conn, "SupplierType", $schema);
|
||||
sqlsrv_query($conn, $dropTableType);
|
||||
|
||||
sqlsrv_query($conn, $dropSchema);
|
||||
$dropTableType = dropTableTypeSQL($conn, "TestTVP3", $schema);
|
||||
sqlsrv_query($conn, $dropTableType);
|
||||
$dropTableType = dropTableTypeSQL($conn, "SupplierType", $schema);
|
||||
sqlsrv_query($conn, $dropTableType);
|
||||
|
||||
sqlsrv_query($conn, $dropSchema);
|
||||
}
|
||||
}
|
||||
|
||||
sqlsrv_configure('LogSeverity', SQLSRV_LOG_SEVERITY_ALL);
|
||||
|
||||
$conn = connect(array('CharacterSet'=>'UTF-8', 'ReturnDatesAsStrings' => true));
|
||||
|
||||
$stmt = sqlsrv_query($conn, "SELECT @@VERSION");
|
||||
if (sqlsrv_fetch($stmt)) {
|
||||
$result = sqlsrv_get_field($stmt, 0);
|
||||
}
|
||||
$version = explode(' ', $result);
|
||||
$pre2016 = ($version[3] < '2016');
|
||||
|
||||
// Use a different schema instead of dbo
|
||||
$schema = 'Sales DB';
|
||||
cleanup($conn, $schema);
|
||||
cleanup($conn, $schema, $pre2016);
|
||||
|
||||
// Create table types and stored procedures
|
||||
sqlsrv_query($conn, $createSchema);
|
||||
|
@ -89,7 +103,7 @@ if (sqlsrv_fetch($stmt)) {
|
|||
}
|
||||
|
||||
fclose($image);
|
||||
cleanup($conn, $schema);
|
||||
cleanup($conn, $schema, $pre2016);
|
||||
|
||||
sqlsrv_free_stmt($stmt);
|
||||
sqlsrv_close($conn);
|
||||
|
|
|
@ -18,10 +18,12 @@ function invokeProc($conn, $proc, $tvpInput, $caseNo, $dir = SQLSRV_PARAM_IN)
|
|||
|
||||
$stmt = sqlsrv_query($conn, $proc, $params);
|
||||
if (!$stmt) {
|
||||
$errors = sqlsrv_errors(SQLSRV_ERR_ALL);
|
||||
// $errors = sqlsrv_errors(SQLSRV_ERR_ALL);
|
||||
$errors = sqlsrv_errors();
|
||||
if (!empty($errors)) {
|
||||
$count = count($errors);
|
||||
}
|
||||
$count = 1;
|
||||
for ($i = 0; $i < $count; $i++) {
|
||||
echo "Error $caseNo: ";
|
||||
echo $errors[$i]['message'] . PHP_EOL;
|
||||
|
@ -29,17 +31,23 @@ function invokeProc($conn, $proc, $tvpInput, $caseNo, $dir = SQLSRV_PARAM_IN)
|
|||
}
|
||||
}
|
||||
|
||||
function cleanup($conn, $schema, $tvpType, $procName)
|
||||
function cleanup($conn, $schema, $tvpType, $procName, $pre2016)
|
||||
{
|
||||
global $dropSchema;
|
||||
|
||||
$dropProcedure = dropProcSQL($conn, "[$schema].[$procName]");
|
||||
sqlsrv_query($conn, $dropProcedure);
|
||||
if ($pre2016) {
|
||||
sqlsrv_query($conn, "DROP PROCEDURE [$schema].[$procName]");
|
||||
sqlsrv_query($conn, "DROP TYPE [$schema].[$tvpType]");
|
||||
sqlsrv_query($conn, "DROP SCHEMA [$schema]");
|
||||
} else {
|
||||
global $dropSchema;
|
||||
|
||||
$dropProcedure = dropProcSQL($conn, "[$schema].[$procName]");
|
||||
sqlsrv_query($conn, $dropProcedure);
|
||||
|
||||
$dropTableType = dropTableTypeSQL($conn, $tvpType, $schema);
|
||||
sqlsrv_query($conn, $dropTableType);
|
||||
|
||||
sqlsrv_query($conn, $dropSchema);
|
||||
$dropTableType = dropTableTypeSQL($conn, $tvpType, $schema);
|
||||
sqlsrv_query($conn, $dropTableType);
|
||||
|
||||
sqlsrv_query($conn, $dropSchema);
|
||||
}
|
||||
}
|
||||
|
||||
sqlsrv_configure('LogSeverity', SQLSRV_LOG_SEVERITY_ALL);
|
||||
|
@ -51,7 +59,14 @@ $schema = 'Sales DB';
|
|||
$tvpType = 'TestTVP3';
|
||||
$procName = 'SelectTVP3';
|
||||
|
||||
cleanup($conn, $schema, $tvpType, $procName);
|
||||
$stmt = sqlsrv_query($conn, "SELECT @@VERSION");
|
||||
if (sqlsrv_fetch($stmt)) {
|
||||
$result = sqlsrv_get_field($stmt, 0);
|
||||
}
|
||||
$version = explode(' ', $result);
|
||||
$pre2016 = ($version[3] < '2016');
|
||||
|
||||
cleanup($conn, $schema, $tvpType, $procName, $pre2016);
|
||||
|
||||
// Create table type and a stored procedure
|
||||
sqlsrv_query($conn, $createSchema);
|
||||
|
@ -163,7 +178,7 @@ $inputs = [
|
|||
$tvpInput = array($tvpTypeName => $inputs);
|
||||
invokeProc($conn, $callSelectTVP3, $tvpInput, 14);
|
||||
|
||||
cleanup($conn, $schema, $tvpType, $procName);
|
||||
cleanup($conn, $schema, $tvpType, $procName, $pre2016);
|
||||
|
||||
sqlsrv_close($conn);
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче