[MSSQL] sqlsrv_free_stmt(): supplied resource is not a valid ss_sqlsrv_stmt resource in
오류 현상
php에 MSSQL(SQL Server) 쿼리 구문을 실행 시 해당 오류 발생
에러 소스코드
<?
...
$db_conn = mssql_conn();
if( ... ) {
$var = $_POST["var"];
...
$query = "select * from {$tb_name} where var={$var}";
$result = sqlsrv_query($db_conn, $query, array(), array( "Scrollable" => 'static' ));
$num = sqlsrv_num_rows($result);
sqlsrv_free_stmt($result);
$query = "delete from {$tb_name} where var={$var}";
sqlsrv_query($db_conn, $query, array(), array( "Scrollable" => 'static' ));
}
sqlsrv_free_stmt($result);
?>
mssql connection 객체를 만들어서,
var 변수가 충족되는 레코드를 select 후 delete하는 코드이다.
구문을 실행 후 C++의 malloc 후 free처럼, 메모리 누수를 방지하기 위해
sqlsrv_free_stmt로 메모리 해제를 해주었다.
원인
line 18: sqlsrv_free_stmt($result)에 문제가 있다.
$result 변수는 전역 변수가 아닌 if문 블록 내에 있는 블록 내 변수이다.
그러므로 sqlsrv_free_stmt 함수는 변수의 라이프사이클 상 $result 변수를 알 수 없다.
소스코드 수정
result 변수가 있는 if 문 내에 sqlsrv_free_stmt 함수를 사용하도록 변경하였다.
또한 sqlsrv_query 실행 후마다 sqlsrv_free_stmt를 사용하였다.
<?
...
$db_conn = mssql_conn();
if( ... ) {
$var = $_POST["var"];
...
$query = "select * from {$tb_name} where var={$var}";
$result = sqlsrv_query($db_conn, $query, array(), array( "Scrollable" => 'static' ));
$num = sqlsrv_num_rows($result);
sqlsrv_free_stmt($result);
$query = "delete from {$tb_name} where var={$var}";
sqlsrv_query($db_conn, $query, array(), array( "Scrollable" => 'static' ));
sqlsrv_free_stmt($result);
}
?>
추가사항
참고로 원래 소스코드에서는 아래 코드처럼
if문이 끝나면 한번 더 마무리로 메모리 해제를 해주는 방식이었는데
로직 상 if/else 문 외에 해당하는 케이스가 없어서
굳이 아래처럼 해줄 필요도 없어 마지막 외부 free문도 삭제하였다.
+ 만약 레코드 검색에 사용할 변수가 문자열이라면 var={$var}이 아닌 var='{$var}'과 같이 쿼리를 작성해야 한다.
<?
...
if ( ... ) {
$query = "select * from {$tb_name} where var={$var}";
$result = sqlsrv_query($db_conn, $query, array(), array( "Scrollable" => 'static' ));
sqlsrv_free_stmt($result);
$query = "delete from {$tb_name} where var={$var}";
sqlsrv_query($db_conn, $query, array(), array( "Scrollable" => 'static' ));
sqlsrv_free_stmt($result);
}
# sqlsrv_free_stmt($result);
?>
참고자료
https://learn.microsoft.com/ko-kr/sql/connect/php/sqlsrv-free-stmt?view=sql-server-ver16
https://stackoverflow.com/questions/16562704/php-sqlsrv-passing-a-resource-from-a-function