Bạn có chắc về điều này? Loại do người dùng xác định là các đối tượng cấp cơ sở dữ liệu, không phải cấp máy chủ. Cách duy nhất để truy cập chúng một cách "phổ biến" là tải Assembly vào từng cơ sở dữ liệu và tạo Kiểu do người dùng xác định trong mỗi cơ sở dữ liệu. Nhiều điều này được nêu trong tài liệu MSDN cho Đăng ký Loại do Người dùng Xác định trong SQL Server :
Để trả lời các câu hỏi cụ thể của bạn:
Cả Loại bảng và Loại do người dùng xác định đều không thể truy cập được trên cơ sở dữ liệu, chấp nhận trong một trường hợp đối với CLR UDT như đã nêu ở trên trong tài liệu MSDN.
Bạn không thể vì đó là hai thứ riêng biệt (tức là "Loại" so với "Loại bảng") thay vì chỉ là hai phương tiện triển khai khác nhau (tức là T-SQL UDF / Stored Proc so với SQLCLR UDF / Stored Proc).
CHỈNH SỬA:
Ở cấp độ kỹ thuật thuần túy, nó là có thể sử dụng Các loại (Loại Bảng và Loại do Người dùng Xác định) trên cơ sở dữ liệu, nhưng chỉ bằng cách chuyển đổi ngữ cảnh hiện tại qua USE
lệnh chỉ có thể sử dụng trong SQL đặc biệt / động. Do đó, cách sử dụng này có khả năng áp dụng hạn chế ở cấp độ thực tế, nhưng dù sao thì nó vẫn có thể xảy ra như ví dụ sau cho thấy:
SET ANSI_NULLS ON;
SET QUOTED_IDENTIFIER ON;
SET NOCOUNT ON;
GO
USE [msdb];
GO
PRINT 'Creating [GlobalTableDef] Table Type in [msdb]...';
CREATE TYPE dbo.GlobalTableDef
AS TABLE
(
[ID] INT NOT NULL IDENTITY(17, 22),
[CreateDate] DATETIME NOT NULL DEFAULT (GETDATE()),
[Something] NVARCHAR(2000) NULL
);
GO
PRINT 'Creating [TotalBytes] Function in [msdb]...';
GO
CREATE FUNCTION dbo.TotalBytes
(
@TableToSummarize dbo.GlobalTableDef READONLY
)
RETURNS INT
AS
BEGIN
DECLARE @TotalBytes INT = 0;
SELECT @TotalBytes += (4 + 8 + DATALENGTH(COALESCE(tmp.Something, '')))
FROM @TableToSummarize tmp;
RETURN @TotalBytes;
END;
GO
PRINT 'Testing the Table Type and Function...';
DECLARE @TmpTable dbo.GlobalTableDef;
INSERT INTO @TmpTable (Something) VALUES (N'this is a test');
INSERT INTO @TmpTable (Something) VALUES (NULL);
INSERT INTO @TmpTable (Something) VALUES (N'still seems to be a test');
SELECT * FROM @TmpTable;
SELECT dbo.TotalBytes(@TmpTable) AS [TotalBytesUsed];
GO
USE [tempdb];
GO
PRINT 'Creating [TypeTest] Proc in [tempdb]...';
GO
CREATE PROCEDURE dbo.TypeTest
AS
SET NOCOUNT ON;
SELECT 1 AS [Step], DB_NAME() AS [CurrentDB];
EXEC('
SELECT 2 AS [Step], DB_NAME() AS [CurrentDB];
USE [msdb];
SELECT 3 AS [Step], DB_NAME() AS [CurrentDB];
DECLARE @TmpTable dbo.GlobalTableDef;
USE [tempdb];
SELECT 4 AS [Step], DB_NAME() AS [CurrentDB];
-- local query to prove context is tempdb
SELECT TOP 5 * FROM sys.objects;
INSERT INTO @TmpTable (Something) VALUES (N''this is a new test'');
INSERT INTO @TmpTable (Something) VALUES (NULL);
INSERT INTO @TmpTable (Something) VALUES (N''non-empty value'');
INSERT INTO @TmpTable (Something) VALUES (NULL);
INSERT INTO @TmpTable (Something) VALUES (N''woo-hoo!!!!!!!!!!!!!!!'');
SELECT * FROM @TmpTable;
SELECT [msdb].dbo.TotalBytes(@TmpTable) AS [TotalBytesUsed];
');
GO
USE [master];
GO
SELECT 5 AS [Step], DB_NAME() AS [CurrentDB];
EXEC tempdb.dbo.TypeTest;
--------------------------------
USE [tempdb];
GO
IF (OBJECT_ID(N'tempdb.dbo.TypeTest') IS NOT NULL)
BEGIN
PRINT 'Dropping [TypeTest] Proc from [tempdb]...';
DROP PROCEDURE dbo.TypeTest;
END;
GO
USE [msdb];
GO
IF (OBJECT_ID(N'dbo.TotalBytes') IS NOT NULL)
BEGIN
PRINT 'Dropping [TotalBytes] Function from [msdb]...';
DROP FUNCTION dbo.TotalBytes;
END;
GO
IF (EXISTS(
SELECT *
FROM sys.table_types stt
WHERE stt.name = N'GlobalTableDef'
))
BEGIN
PRINT 'Dropping [GlobalTableDef] Table Type from [msdb]...';
DROP TYPE dbo.GlobalTableDef;
END;
GO