dswitzer
02/14/2023, 6:26 PM<cfquery name="text">
select <cfqueryparam cfsqltype="CF_SQL_CHAR" value="2" />
</cfquery>
And then I monitored the actual SQL that SQL Server executes, I'm seeing the cached plan end up as:
exec sp_executesql N'select @P0',N'@P0 nvarchar(4000)',N'2'
Notice that instead of 2 being cast as char(1) it's cast as an nvarchar(4000). Any of the string values are behaving the same way.
Shouldn't the executed SQL look like this instead:
exec sp_executesql N'select @P0',N'@P0 char(1)','2'Patrick S
02/14/2023, 6:29 PMsteveduke
02/14/2023, 6:29 PMdswitzer
02/14/2023, 6:29 PMdswitzer
02/14/2023, 6:29 PMdswitzer
02/14/2023, 6:31 PMPatrick S
02/14/2023, 6:34 PMdswitzer
02/14/2023, 6:39 PMsteveduke
02/14/2023, 6:47 PMdswitzer
02/14/2023, 6:49 PMdswitzer
02/14/2023, 7:00 PMsendStringParametersAsUnicode does send the string as a varchar instead of an nvarchar, but it always ignores the maxlength and never actual sends as a char(1) .dswitzer
02/14/2023, 7:02 PMzackster
02/14/2023, 10:28 PMzackster
02/15/2023, 12:49 AMdswitzer
02/15/2023, 11:50 AMchar datatype, even though the JDBC spec allows it. Is that correct?zackster
02/15/2023, 10:08 PMcarehart
02/24/2023, 5:14 AMdswitzer
02/24/2023, 1:10 PMsendStringParametersAsUnicode does always send all params as internationalized datatypes (i.e. "n"). This is per the JDBC spec.
However, from what I can tell there, the MS JDBC driver will always translate "string" parameters to varchar or nvarchar datatypes:
https://github.com/microsoft/mssql-jdbc/blob/9cbaf1754194c4a6391e192f12fc59df7ad3ee03/src/main/java/com/microsoft/sqlserver/jdbc/Parameter.java#L717
From what I can determine, there does not appear to be any performance issue with comparing varchar parameters to columns stored as char datatypes. The main difference is internally in how SQL Server stores the value. SQL Server shows no signs of any implicit datatype conversions comparing char-to-varchar/nchar-to-nvarchar.
It does seem like Lucee could specify sending the size of the varchar/nvarchar datatype, but looking at the ACF docs, it does not actually state that maxLength does anything with the database, it just validates before the string is sent to the DB.
So the take away for me is:
1. The docs for sendStringParametersAsUnicode setting (i.e. "Send String Parameters as Unicode") should be more clear that enabling this will always send all parameters as internationalized and will ignore the datatype you specify in the cfqueryparam. My guess is this probably effects a lot of people and they are unaware. This can definitely cause performance issues if your database is using any char/varchar columns.
2. The docs for cfqueryparam should be updated to indicate that the datatype you specify, may not be the datatype that is acutally used when the parameter is translated to DB. From what I can see, you could just declare all string datatypes as varchar/nvarchar and not see any different between using char/nchar/varchar/nvarchar.carehart
03/05/2023, 5:33 AM