I have a PHP application powered by Lumen framework and trying to query a table that's encrypted using Always Encrypted feature from SQL server.
I am trying to retrieve data from a table with encrypted column using SELECT
query with WHERE
clause on the encrypted column.
From the documentation here, we should be able to do it like this
DECLARE @FirstName NVARCHAR(MAX) = 'Paul';
SELECT * FROM t_users_encrypted WHERE first_name = @FirstName;
where t_users_encrypted.first_name
is an encrypted column with NVARCHAR(MAX)
data type. I've tried running that query in SSMS and it works fine.
However I've had a problem when trying to run that query in Lumen, this is what I've tried
app('db')->select(
"DECLARE @FirstName NVARCHAR(MAX) = 'Paul';
SELECT * FROM t_users_encrypted WHERE first_name = @FirstName"
);
and it returns error
SQLSTATE[42000]: [Microsoft][ODBC Driver 17 for SQL Server][SQL Server]Encryption scheme mismatch for columns/variables '@FirstName'. The encryption scheme for the columns/variables is (encryption_type = 'PLAINTEXT') and the expression near line '2' expects it to be DETERMINISTIC, or PLAINTEXT. (SQL: DECLARE @FirstName NVARCHAR(MAX) = 'Paul';
SELECT * FROM t_users_encrypted WHERE first_name = @FirstName)
Is there anything wrong with the query or maybe I'm using wrong function? or is it not possible to use the built in Lumen library?
EDIT:
Turns out based on this,
Rely on the PHP driver to determine and set the right SQL type. In this case, the user must use
sqlsrv_prepare
andsqlsrv_execute
to execute a parameterized query.
So basically we need to use a specific function from sqlsrv
or pdo_sqlsrv
driver, using those driver function directly I manage to make a raw query work, i.e. normal select query with prepared statement work fine without need to declare a variable as follows
$query = "SELECT * FROM t_users_encrypted WHERE first_name = ?";
$firstName = "Paul";
$params = [&$firstName];
$stmt = sqlsrv_prepare($conn, $query, $params);
So I guess my question is, is there any built in Lumen/Laravel function that could achieve this? or should I use the driver function directly and probably build the wrapper myself?