none
跨数据库使用用户定义类型 RRS feed

  • 问题

  • CREATE TYPE [dbo].[KeyValue] 
    AS TABLE(
        [key] VARCHAR(50),
        [value] varchar(500)null
    )
    go 
    比如
    A数据库建立了KeyValue类型,并建立了存储过程P1,其中P1参数就是KeyValue。
    B数据库里面有个存储过程P2。B是链接服务器。
    我现在想在P2中调用P1。但是P1的参数却无法声明,怎么办呢?

    http://msdn.microsoft.com/zh-cn/library/ms178069(v=sql.100).aspx

    微软的解释也不含糊不清。 

    2013年5月8日 6:22

答案

  • 表类型不太一样, 就算不用链接服务器, 同一服务器的
    USE tempdb;
    go
    CREATE TYPE [dbo].[KeyValue] 
    AS TABLE(
        [key] VARCHAR(50),
        [value] varchar(500)null
    )
    GO
    CREATE PROC dbo.p
    	@tb AS [dbo].[KeyValue] READONLY
    AS
    SELECT * FROM @tb 
    GO
    
    USE master;
    GO
    CREATE TYPE [dbo].[KeyValue] 
    AS TABLE(
        [key] VARCHAR(50),
        [value] varchar(500)null
    )
    GO
    DECLARE @tb AS [dbo].[KeyValue];
    INSERT @tb VALUES(1, 1);
    SELECT * FROM @tb;
    EXEC tempdb.dbo.p @tb;
    /*-- 这里会报错
    消息 206,级别 16,状态 2,过程 p,第 0 行
    操作数类型冲突: KeyValue 与 KeyValue 不兼容
    --*/
    GO
    
    DROP TYPE [dbo].[KeyValue] ;
    GO
    USE tempdb;
    GO
    DROP PROC dbo.p
    DROP TYPE [dbo].[KeyValue] 

    两库都不行, 暂时没有找到具体的说明和可行的方法
    2013年5月8日 13:42

全部回复

  • LZ你给出的MSDN链接不是说的比较清楚的了,你需要在两个数据库都要创建相同的用户定义数据类型

    当您跨数据库使用用户定义类型时,应该记住下列事项:

    类型必须具有相同的名称(包括相同 CLR 名称),且必须在两个数据库中通过相同的程序集来实现。两个数据库中的程序集相同的条件是:具有相同的名称、强名称、区域性、版本、代码访问权限集以及二进制内容。

    您必须具有对查询中引用的每个用户定义类型列的 SELECT 和 EXECUTE 权限。这些权限将根据定义各列的数据库进行检查。

    如果某个程序集中实现的类型调用了其他程序集中的方法,将检查跨程序集调用,检查方式就像没有跨数据库发出用户定义类型的查询一样。

    两个数据库都要创建同样的自定义数据类型

    又或者是你是链接服务器的原因,所以无法使用跨数据库定义数据类型


    给我写信: QQ我:点击这里给我发消息

    2013年5月8日 12:25
  • 表类型不太一样, 就算不用链接服务器, 同一服务器的
    USE tempdb;
    go
    CREATE TYPE [dbo].[KeyValue] 
    AS TABLE(
        [key] VARCHAR(50),
        [value] varchar(500)null
    )
    GO
    CREATE PROC dbo.p
    	@tb AS [dbo].[KeyValue] READONLY
    AS
    SELECT * FROM @tb 
    GO
    
    USE master;
    GO
    CREATE TYPE [dbo].[KeyValue] 
    AS TABLE(
        [key] VARCHAR(50),
        [value] varchar(500)null
    )
    GO
    DECLARE @tb AS [dbo].[KeyValue];
    INSERT @tb VALUES(1, 1);
    SELECT * FROM @tb;
    EXEC tempdb.dbo.p @tb;
    /*-- 这里会报错
    消息 206,级别 16,状态 2,过程 p,第 0 行
    操作数类型冲突: KeyValue 与 KeyValue 不兼容
    --*/
    GO
    
    DROP TYPE [dbo].[KeyValue] ;
    GO
    USE tempdb;
    GO
    DROP PROC dbo.p
    DROP TYPE [dbo].[KeyValue] 

    两库都不行, 暂时没有找到具体的说明和可行的方法
    2013年5月8日 13:42
  • 要在 Microsoft SQL Server 中使用用户定义类型 (UDT),必须注册该类型。 注册一个 UDT 涉及两个步骤:在要使用它的数据库中注册程序集和创建该类型。 UDT 的作用域仅限单个数据库,不能在多个数据库中使用,除非在各个数据库中注册相同的程序集和 UDT。 一旦注册 UDT 程序集并创建了该类型,即可在 Transact-SQL 和客户端代码中使用

    http://technet.microsoft.com/zh-cn/library/ms131079.aspx

    http://technet.microsoft.com/zh-cn/library/ms131106(v=SQL.105).aspx

    http://technet.microsoft.com/zh-cn/library/ms190232(v=SQL.90).aspx


    给我写信: QQ我:点击这里给我发消息

    2013年5月9日 4:05