从表SQL服务器管理

时间:2016-05-04 09:49:39

标签: sql sql-server sql-server-2014

我是SQL Server的新手。我试图创建一个存储过程,让我得到一些我要求的行。这是我有的数据表: Datatable

所以,让我说我想展示所有拥有TMS1和标识符88和89的车辆。我该怎么写?目前我有代码

ALTER Procedure [db_ddladmin].[spGetVehicles]@ECU nvarchar(20),


@Identifier nvarchar(20)
  as
  Begin 
  Select * FROM db_ddladmin.View_VehicleReadouts where ECU = @ECU and Identifier = @Identifier
  End

  exec [db_ddladmin].[spGetVehicles] 'EBS7', '91'

这给了我所有带有ECU EBS7和标识符91的车辆。让我们在ECU EBS7上使用标识符90。我该怎么写?我可以使用OR语句,但这会给我重复的车辆,我不想要。

4 个答案:

答案 0 :(得分:0)

您可以使用用户定义的表格类型:

create  type dbo.YourNames as table (name varchar(10))
go
declare @names dbo.YourNames
insert into @names values ('ECU'),('EBS7')
select * from @names
select * 
from db_ddladmin.View_VehicleReadouts v join @names on v.ECU = @names.name

答案 1 :(得分:0)

如果潜在标识符的数量未知,则一个选项是将标识符作为逗号分隔的字符串传递。遗憾的是,您将无法直接将逗号分隔的字符串与源表标识符进行比较,您首先必须将标识符字符串拆分为单独的表。这可以通过表值函数来完成。我在堆栈溢出处发现了以下拆分字符串代码示例,应该可以完成这项工作。

    SET ANSI_NULLS ON
    GO

    SET QUOTED_IDENTIFIER ON
    GO

    CREATE FUNCTION [dbo].[SplitString]
            (@pString NVARCHAR(4000), @pDelimiter NCHAR(1))
    RETURNS TABLE WITH SCHEMABINDING AS
     RETURN
      WITH E1(N) AS (
                     SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL
                     SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL
                     SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1
                    ),                          --10E+1 or 10 rows
           E2(N) AS (SELECT 1 FROM E1 a, E1 b), --10E+2 or 100 rows
           E4(N) AS (SELECT 1 FROM E2 a, E2 b), --10E+4 or 10,000 rows max
     cteTally(N) AS (--==== This provides the "base" CTE and limits the number of rows right up front
                         -- for both a performance gain and prevention of accidental "overruns"
                     SELECT TOP (ISNULL(DATALENGTH(@pString),0)) ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) FROM E4
                    ),
    cteStart(N1) AS (--==== This returns N+1 (starting position of each "element" just once for each delimiter)
                     SELECT 1 UNION ALL
                     SELECT t.N+1 FROM cteTally t WHERE SUBSTRING(@pString,t.N,1) = @pDelimiter
                    ),
    cteLen(N1,L1) AS(--==== Return start and length (for use in substring)
                     SELECT s.N1,
                            ISNULL(NULLIF(CHARINDEX(@pDelimiter,@pString,s.N1),0)-s.N1,8000)
                       FROM cteStart s
                    )
    --===== Do the actual split. The ISNULL/NULLIF combo handles the length for the final element when no delimiter is found.
     SELECT ItemNumber = ROW_NUMBER() OVER(ORDER BY l.N1),
            Item       = SUBSTRING(@pString, l.N1, l.L1)
       FROM cteLen l
       WHERE SUBSTRING(@pString, l.N1, l.L1) <> ''
    ;
    GO

将功能添加到数据库后,您可以按照以下步骤更新您的程序:

    ALTER Procedure [db_ddladmin].[spGetVehicles]
    (
        @ECU nvarchar(20),
        @Identifiers nvarchar(20)
    )
    AS
    Begin 

      SELECT    * 
      FROM  db_ddladmin.View_VehicleReadouts where ECU = @ECU 
                and 
            Identifier IN (SELECT Item  FROM [dbo].[SplitString]( @Identifiers, ',' ) )

    END

您现在可以执行以下步骤:

    EXEC [db_ddladmin].[spGetVehicles] @ECU = 'EBS7', @Identifiers = '88,89'

答案 2 :(得分:0)

爱德蒙,这就是我的代码现在的样子。

Alter Procedure [db_ddladmin].[spGetVehicles]
(
    @ECU nvarchar(20),
    @Identifiers nvarchar(20),
    @Value nvarchar(20)



)
AS
Begin 

  SELECT    * 
  FROM  db_ddladmin.View_VehicleReadouts where ECU IN (Select Item FROM [dbo].[SplitString](@ECU,',') )
            and 
        Identifier IN (SELECT Item  FROM [dbo].[SplitString]( @Identifiers, ',' ) )
        and
        Value in (Select Item From [dbo].[SplitString]( @Value, ',' ) );


        with items(item) as (
  select Item 
  from dbo.SplitString(@Value, ',') )
 select Name
 from db_ddladmin.View_VehicleReadouts
 where Value in (select items.item from items)
 group by Name
 having count(distinct value) = (select count(*) from items);


END

我使用

执行
EXEC [db_ddladmin].[spGetVehicles] @ECU = 'EBS7, DIS2', @Identifiers = '88,94', @Value = '2459579, 8.0.0'

如果我只使用一个ECU。有用。例如,如果我有EBS7,那就是结果:

Result of a execution

正如你可以看到的那样,当我只有一个ECU写入时它可以正常工作,但是当我尝试使用两个ECU时它没有工作,有什么建议吗?

为了您的信息,所有ecu都与某些标识符相关联。所有标识符都有一些特定的值,这些值对于该ECU的标识符是唯一的

答案 3 :(得分:-1)

您可以使用列表作为逗号分隔的参数。 然后在你的where子句中,你可以这样做:

Identifier IN @IdentifierList

通过这种方式,您可以从列表中选择多个记录。 这是你想要的吗?

即。

  

所以,假设我想展示所有拥有TMS1和TMS1的车辆   标识符88和89

EXEC [db_ddladmin].[spGetVehicles] 'TMS1', '88,89'

Reference for IN Clause

Reference for using a list as parameter in IN Clause