Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/86.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
从SQL server管理表中选择几行_Sql_Sql Server_Sql Server 2014 - Fatal编程技术网

从SQL server管理表中选择几行

从SQL server管理表中选择几行,sql,sql-server,sql-server-2014,Sql,Sql Server,Sql Server 2014,我对SQL Server非常陌生。我正在尝试创建一个存储过程,以获得我需要的一些行。这是我的数据表: 假设我想展示所有具有TMS1和标识符88和89的车辆。我应该写什么?目前我有密码 ALTER Procedure [db_ddladmin].[spGetVehicles]@ECU nvarchar(20), @Identifier nvarchar(20) as Begin Select * FROM db_ddladmin.View_VehicleReadouts whe

我对SQL Server非常陌生。我正在尝试创建一个存储过程,以获得我需要的一些行。这是我的数据表:

假设我想展示所有具有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。我应该写什么?我可以使用OR语句,但这会给我重复的车辆,我不想要

可以使用列表作为由逗号分隔的参数。 然后在where子句中,您可以执行以下操作:

Identifier IN @IdentifierList
这样,您就可以从列表中选择多个记录。 这是你想要的吗

i、 e

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


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

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

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

    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'

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

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,结果如下:

正如您所能看到的,当我只编写了一个ECU时,它就工作了,但是当我尝试使用两个ECU时,它就不工作了,有什么建议吗


供您参考,所有ecu都与一些标识符链接。所有标识符都有一些特定值,这些值对于该ecu的标识符是唯一的

是的,这是我想要的。你能再解释一下吗?你能试一下并发布脚本吗?嗨,对不起,正在做一些事情,但我已经亲自尝试过了。检查此引用:对identifier子句执行类似于该线程答案的IN子句;所以你实际上是想说dinamic sqlWow谢谢你,我会试试这个,然后回来看看它是否有效。假设我想对ecu做同样的事情,假设我有不同的ecu,也有不同的标识符,这样行吗?我刚刚注意到我给出的示例中有一个错误。SplitString函数需要第二个参数,该参数定义字符串的分隔符(在本例中为逗号)。IN子句应如下所示:Identifier IN SELECT Item FROM[dbo].[SplitString]@Identifiers',“我已经更新了示例以反映更正。非常感谢@Edmond。我还有一个小问题。当我执行存储过程时,我得到一个包含ecu ebs7中标识符88,89的所有车辆的列表。但问题是它显示了双倍。例如,车辆Aura在ECu EBS7中同时具有标识88和89,因此在列表中它被列出两次。一次id为88,一次id为89,是否有办法只显示一次?我注意到一件事,如果我为ecu创建一个IN列表,假设我想要所有带有ecu EBS7和ALM1的车辆,当我执行存储过程时,我会得到所有威瑟尔拥有EBS7或ALM1或两者的车辆。我不想展示有ebs7但没有alm1的车辆。我只想列出同时具有alm1和EBS7的所有车辆。如果我正确理解您的第一个问题,您希望在ECu中获得与您的标识符匹配的车辆的不同记录。如果是这种情况,您可以简单地在中使用'DISTINCT'子句,但您必须将列限制为仅返回车辆和ECu。如果您想包括其他列,例如标识符列,该列在每个ECu和车辆中可能有多个条目,那么您首先必须决定如何处理这些列。例如,如果88和89都是Aura的有效标识符,那么您的记录中应该返回哪些标识符?或的问题只是括号:其中ECU=@ECU和identifier=90或identifier=91,另一个选项是说identifier in 90,91,这有助于避免优先级问题。
EXEC [db_ddladmin].[spGetVehicles] @ECU = 'EBS7, DIS2', @Identifiers = '88,94', @Value = '2459579, 8.0.0'