user defined datatypes, i'm looking at some execution plans and seeing implicit conversions happening in the background when a var is declared of type user defined data type and pulling a value into that var from a column that uses that user defined data type, it's showing it as an implicit conversion. Is this how it functions normally?
Added
ok so under Programmability -> Types -> User-Defined Data Types: there is
dbo.BOOL(char(1), not null)
and
ImageAccessibleFLAG TYPE_NAME is BOOL
New test
I can make an implicit conversion happen by doing the following reasonforcreatetype is char(1) in the database
declare @test char(1)
set @test = (select top 1 reasonforcreatetype from result)
select @test
<ScalarOperator ScalarString="CONVERT_IMPLICIT(char(1),[Result].[ReasonForCreateType],0)">
Now I create a new table with a char(1) and a bool. Run the same query and I don't get the implicit conversion.
Update 2
Ok when adding a new column under the same table having the issue I get the following
Warning: Columns have different ANSI_PADDING settings.
New columns will be created with ANSI_PADDING 'on'.
I'm assuming this has something to do with it now but I'm not sure the proper way to fix or correct these issues.
1 Answer 1
Okay, here is a repro:
USE tempdb;
GO
-- create one table with padding off:
SET ANSI_PADDING OFF;
GO
CREATE TABLE dbo.ap_off(a CHAR(1),
CONSTRAINT ck_apOff CHECK (a IN ('N','Y')));
GO
-- and other with padding on:
SET ANSI_PADDING ON;
GO
CREATE TABLE dbo.ap_on(a CHAR(1),
CONSTRAINT ck_apOn CHECK (a IN ('N','Y')));
GO
-- now, let's test queries
-- with padding on or off
SET ANSI_PADDING OFF;
GO
-- implicit conversion:
DECLARE @off CHAR(1) = (SELECT a FROM dbo.ap_off);
-- implicit conversion:
DECLARE @on CHAR(1) = (SELECT a FROM dbo.ap_on);
SET ANSI_PADDING ON;
GO
-- implicit conversion:
DECLARE @off CHAR(1) = (SELECT a FROM dbo.ap_off);
-- NO implicit conversion:
DECLARE @on CHAR(1) = (SELECT a FROM dbo.ap_on);
GO
DROP TABLE dbo.ap_off, dbo.ap_on;
Here's the same version of the plan for the first three queries:
enter image description here
And the fourth, missing the compute scalar and any implicit conversion:
enter image description here
So, as I suggested above, this doesn't have anything to do with alias types, but rather the fact that ANSI_PADDING
is problematic in a whole bunch of ways (here's a timely article, a Stack Overflow question, and Microsoft's own documentation from SQL Server 2005 telling you to stop using it).
My suggested approach is to build new versions of any table with these non-ANSI_PADDING
columns (this time with ANSI_PADDING ON
of course), migrate the data, drop the old tables, and rename the new tables. Or do the same type of thing with just the individual columns (in either case it's going to be a complicated and disruptive thing that you'll likely want to do during a maintenance window).
You can identify the affected tables with:
SELECT s.name, t.name
FROM sys.schemas AS s
INNER JOIN sys.tables AS t
ON s.[schema_id] = t.[schema_id]
WHERE t.is_ms_shipped = 0
AND EXISTS (SELECT 1 FROM sys.columns
WHERE [object_id] = t.[object_id]
AND is_ansi_padded = 0);
I would do this with one table or columns first, to see if it's worth it. See, in addition to eliminating the implicit conversions (which you think might cause performance issues), you should also demonstrate that performance will actually be different without them - and different enough to justify the effort, risk, and potential downtime. Otherwise, is it worth doing? We can't answer that, only you and your stakeholders can.
-
There are 1,706 tables with this issue. What would be the best way to correct all of these?Tsukasa– Tsukasa2014年08月11日 15:21:13 +00:00Commented Aug 11, 2014 at 15:21
-
@Tsukasa Honestly, the simplest way would be to generate a new, empty database, script all of the objects (you can use comparison tools like Red-Gate's SQL Compare), search/replace the script and make sure ANSI_PADDING is always ON, create the objects, migrate the data (perhaps using Red-Gate's SQL Data Compare), backup the old database, take it offline / drop / detach, then rename the new database.Aaron Bertrand– Aaron Bertrand2014年08月11日 15:39:25 +00:00Commented Aug 11, 2014 at 15:39
Explore related questions
See similar questions with these tags.