I have some weird behavior happening with a parameter passed by reference to a SQL Server Stored Procedure.
I have a variable ($FormType2) in a parameter array passed to the Stored Procedure. When the Stored Procedure is executed and I output the variable, it contains 8000 characters from a different PHP file.
The PHP file in question is included at the top of the majority of my PHP files, because it contains my frequently used functions. I don’t understand how its contents could be assigned to a variable after my SQL Query.
The Stored Procedure assigns the value of @FormType and inserts a set of XML data into a temporary table, then outputs the temp table.
Expected output:
Pre-Execute:<br>-_-_-_-<br>
Post-Execute:<br>Termination<br>
{"PAFIndex":504,"TerminationType":"Involuntary","TerminationName":"205,207,210,403","PolicyName":"TEST","OtherText":"TEST"}"
Actual Results:
Pre-Execute:<br>-_-_-_-<br>
Post-Execute:<br>-_-_-_-H:i:s', time());
//*// 8000 characters from Functions.php starting from Position 25 in the file //*//<br>
{"PAFIndex":504,"TerminationType":"Involuntary","TerminationName":"205,207,210,403","PolicyName":"TEST","OtherText":"TEST"}"
Here is the PHP code for my parameters.
$xmlNewVals = new SimpleXMLElement("<?xml version='1.0'?><data></data>");
array_to_xml($NewVals, $xmlNewVals);
echo "nXML Data:<br>{$xmlNewVals->asXML()}<br>n"; //Confirm XML data accuracy
unset($FormType2);
$FormType2 = "-_-_-_-"; //Initialize the value.
$stmtParams[] = array($PAFIndex, SQLSRV_PARAM_IN);
$stmtParams[] = array($TimeStamp, SQLSRV_PARAM_IN);
$stmtParams[] = array($xmlNewVals->asXML(), SQLSRV_PARAM_IN, SQLSRV_PHPTYPE_STREAM(SQLSRV_ENC_CHAR), SQLSRV_SQLTYPE_XML);
$stmtParams[] = array($_SESSION['UserName'], SQLSRV_PARAM_IN);
$stmtParams[] = array($NewValReason, SQLSRV_PARAM_IN);
$stmtParams[] = array(&$FormType2, SQLSRV_PARAM_INOUT); //Variable passed by reference.
$stmt = "{call HR.PAFAlterChecks(?".str_repeat(",?", count($stmtParams)-1).")}";
echo "nPre-Execute:<br>{$FormType2}<br>n"; //Correctly contains the initialized value.
$result = ExecSQL($stmt, $hasrows, $stmtParams);
echo "nPost-Execute:<br>{$FormType2}<br>n"; //Contains 8000 characters of my Function.php file.
My ExecSQL function contains the following.
function ExecSQL($SQL, &$hasRows = false, $Parameters = array(), $BypassError = false)
{
global $presql, $postsql, $SQLconnection, $GenericErrorMessage;
unset($Result, $Error);
$Error = "";
if(empty($Parameters)){ $SQL = $presql.$SQL.$postsql; }
$Result = sqlsrv_query($SQLconnection, $SQL, $Parameters);
if(empty($Result)){
$Errors = sqlsrv_errors();
foreach($Errors as $i => $err)
{
$Error .= $i.": ".$err['message']." ";
}
$Error .= " ({ ".$SQL." }) ";
echo "<br><br>n";
print_r($Parameters); //testing only, commented in production
echo "<br><br>n";
}
else
{
do { $hasRows = sqlsrv_has_rows($Result); }
while($hasRows === false && sqlsrv_next_result($Result));
}
if(!empty($Error) && empty($BypassError)){
$bug = debug_backtrace();
$res = Error(substr($bug[0]['file'], strrpos($bug[0]['file'], '\')+1), $Error, $bug[0]['line']);
die($GenericErrorMessage."rnt".$Error);
}
return $Result;
}
This is my Stored Procedure.
USE [FormsDataTest]
GO
/****** Object: StoredProcedure [HR].[PAFAlterChecks] Script Date: 05/09/2024 1:09:58 PM ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER PROCEDURE [HR].[PAFAlterChecks]
-- Add the parameters for the stored procedure here
@PAFIndex INT,
@TimeStamp DATETIME = '',
@NewVal XML,
@Verifier NVARCHAR(50) = '',
@NewValReason NVARCHAR(MAX) = '',
@FormType NVARCHAR(15) OUT
AS
BEGIN
SET NOCOUNT ON;
BEGIN TRY
BEGIN TRANSACTION
SET @FormType = (SELECT [FormType] FROM HR.PersonnelAction WHERE [index] = @PAFIndex);
DECLARE @xmlHandle INT
EXEC sys.sp_xml_preparedocument @xmlHandle OUTPUT, @NewVal
SELECT @PAFIndex AS [PAFIndex], * INTO #NewValues
FROM OPENXML(@xmlHandle, '/data', 2)
WITH ([TerminationType] NVARCHAR(50),
[TerminationName] NVARCHAR(MAX),
[PolicyName] NVARCHAR(MAX),
[OtherText] NVARCHAR(MAX)
)
EXEC sys.sp_xml_removedocument @xmlHandle
SELECT * FROM #NewValues --just making sure the xml was input correctly
DROP TABLE #NewValues
COMMIT TRANSACTION
END TRY
BEGIN CATCH
ROLLBACK TRANSACTION
END CATCH
END
GO
If I comment out the line “SELECT * FROM #NewValues” in the stored Procedure, I get the Expected Results in the $FormType2 variable. Which confuses me even more, rather than narrow anything down…