Skip to content

Truncated varchars in Stored Procedures #496

Open
@mrcook

Description

@mrcook

SQL statements are generated using stored procedures, but SQL Server will truncate varchar values to the limit as given in the column. As an example, I create a migration like so:

create_table :users do |t|
  t.string :code, unique: true, limit: 5
end

And then then create a new record giving code the value ABCDE.

A typical SQL query generated by the gem would be:

EXEC sp_executesql N'SELECT  [users].* FROM [users] WHERE [users].[code] = @0  ORDER BY [users].[id] ASC OFFSET 0 ROWS FETCH NEXT 1 ROWS ONLY', N'@0 nvarchar(5)', @0 = N'ABCDEFGH'

If I execute this directly on MSSQL the value ABCDEFGH would be truncated down to ABCDE because of the nvarchar(5) casting, and so we get the record back. This happens while fetching records as well as inserting, and likely other actions too. ActiveRecord validations will not catch these behaviours.

Here's an SO post with some more details on this known MSSQL behaviour: http://stackoverflow.com/questions/4628140/sql-server-silently-truncates-varchars-in-stored-procedures

A proposed solution is to use nvarchar(max), even though there would be a small performance hit.

If I hack the gem to make this change (.sub(/nvarchar\(\d+\)/, 'nvarchar(max)')) then an insert will no longer truncate (desired behaviour), a .where would fail to return the record (as expected), and ActiveRecord validations on length would kick in.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions