mssql 사용하는데 sql_display_size 에러관련
본문
MS-SQL과 PHP 환경입니다.
DB 테이블에 있는 pass는 nvarchar(max)로 변경 후 HASHBYTES 값을 가져오는데
가져온 pass 와 입력된 PW를 비교하려고
단순 "SELECT HASHBYTES('SHA2_256' , '1234') AS PW" 를 호출하면
sqlsrv_fetch_array에서 sql_display_size 에러가 나네요..
그리고 sqlsrv_fetch만 사용하면 1이라는 값이 넘어옵니다.
어디가 문제인지...
조언 구합니다.
답변 1
https://pecl.php.net/package/sqlsrv
에서 최신 패키지 5.10.1 소스 확인해보면
shared/core_stmt.cpp
에 sql_display_size 관련 정의부가 있습니다.
1631 void get_field_as_string(_Inout_ sqlsrv_stmt *stmt, _In_ SQLUSMALLINT field_index, _Inout_ sqlsrv_phptype sqlsrv_php_type,
1632 _Inout_updates_bytes_(*field_len) void *&field_value, _Inout_ SQLLEN *field_len)
1633 {
1634 SQLRETURN r;
1635 SQLSMALLINT c_type;
1636 SQLSMALLINT sql_field_type = 0;
1637 SQLSMALLINT extra = 0;
1638 SQLLEN field_len_temp = 0;
1639 SQLLEN sql_display_size = 0;
1640 char* field_value_temp = NULL;
1641 unsigned int initial_field_len = INITIAL_FIELD_STRING_LEN;
1642
1643 try {
...
1685 // If this is a large type, then read the first chunk to get the actual length from SQLGetData
1686 // The user may use "SET TEXTSIZE" to specify the size of varchar(max), nvarchar(max),
1687 // varbinary(max), text, ntext, and image data returned by a SELECT statement.
1688 // For varbinary(max), varchar(max) and nvarchar(max), sql_display_size will be 0, regardless
1689 if (sql_display_size == 0 ||
1690 (sql_field_type == SQL_WLONGVARCHAR || sql_field_type == SQL_LONGVARCHAR || sql_field_type == SQL_LONGVARBINARY)) {
1691
1692 field_len_temp = initial_field_len;
1693 field_value_temp = static_cast<char*>(sqlsrv_malloc(field_len_temp + extra + 1));
1694 r = stmt->current_results->get_data(field_index + 1, c_type, field_value_temp, (field_len_temp + extra), &field_len_temp, false /*handle_warning*/);
1695 } else {
1696 field_len_temp = sql_display_size;
1697 field_value_temp = static_cast<char*>(sqlsrv_malloc(sql_display_size + extra + 1));
1698
1699 // get the data
1700 r = stmt->current_results->get_data(field_index + 1, c_type, field_value_temp, sql_display_size + extra, &field_len_temp, false /*handle_warning*/);
1701 }
1702
1703 CHECK_CUSTOM_ERROR((r == SQL_NO_DATA), stmt, SQLSRV_ERROR_NO_DATA, field_index) {
1704 throw core::CoreException();
...
1688 라인의 주석에서 sql_display_size 가 0 이 된다고 나와있고
1686 라인에서 사용자가 SET TEXTSIZE 옵션을 지정할 수 있다고 나와있는데
관련 키워드로 검색해보니
php.ini 에
; Valid range 0 - 2147483647. Default = 4096.
mssql.textlimit = 2147483647
; Valid range 0 - 2147483647. Default = 4096.
mssql.textsize = 2147483647
또는 php 코드에 임시 형태로
ini_set('mssql.textlimit', '2147483647');
ini_set('mssql.textsize', '2147483647');
sqlsrv_query($conn, 'SET TEXTSIZE 2147483647');
이정도로 사용하는것 같습니다만 2147483647 = signed int 최대 크기(대략 2G) 입니다.
필요한 옵션이라면 주의해서 적절성 여부 판별 후 사용설정 하셔야 할것 같네요.
또 mssql_* 프리픽스 함수들은 PHP 7.0.0 부터는 삭제되고
sqlsrv_* 프리픽스 함수들이 사용되는데
관련 설정 옵션 값도 mssql.* 이 아닌 다른 값이 아닌가 싶습니다. (sqlsrv.* ?)
아니면 임시로 필드타입을 바꿔서 테스트 해보는것도 방법일것 같습니다.
그리고 sqlsrv_fetch 함수의 경우 1이 출력 된다는 것은
https://www.php.net/manual/en/function.sqlsrv-fetch.php
에서 true 가 return 되었다는 뜻이고
읽을수 있는 데이터행이 준비되었다는 의미입니다.
!-->!-->!-->