Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/76.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/21.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 2008_Tsql - Fatal编程技术网

交换SQL Server中的选定行

交换SQL Server中的选定行,sql,sql-server,sql-server-2008,tsql,Sql,Sql Server,Sql Server 2008,Tsql,我尝试交换所选行,作为用户选择与其已选择的相反行的快捷方式 例如: 当前选择: ID SelectedUID ------------------ 1 2 3 CJ 4 5 DECLARE @table TABLE (ID INT, SelectedUID VARCHAR(5)) INSERT INTO @table VALUES (1, ''),

我尝试交换所选行,作为用户选择与其已选择的相反行的快捷方式

例如:

当前选择:

ID    SelectedUID
------------------
1         
2         
3         CJ
4         
5         
DECLARE @table TABLE (ID INT,
                  SelectedUID VARCHAR(5))
INSERT INTO @table
VALUES  (1, ''),
       (2, ''),
       (3, 'CJ'),
       (4, ''),
       (5, '')

SELECT ID,SelectedUID
FROM @table

--USAGE WITH SELECT

SELECT ID,
      dbo.udf_SwapValues(SelectedUID, 'CJ', '')
FROM @table

--USAGE WITH UPDATE
UPDATE t
SET t.SelectedUID = dbo.udf_SwapValues(t.SelectedUID, 'CJ', '')
FROM @table t

SELECT *
FROM @table
交换选择:(这就是我试图实现的目标)

在SQL Server中有没有函数或简单的方法来实现这一点

编辑

这是一个合适的存储过程吗?执行此操作时,我收到一个错误

CREATE PROCEDURE [dbo].[ProcSWAPSelections]
@FROMCLAUSE AS VARCHAR(8000),
@UPDATETABLE AS VARCHAR(50),
@GUID AS VARCHAR(3),
@WHERECLAUSE AS VARCHAR(8000)

AS 
BEGIN 
SET NOCOUNT ON;

DECLARE @SQL NVARCHAR(MAX);

SET @SQL = N'UPDATE ' + @UPDATETABLE + '
             SET Selected' + @GUID + '.UID = CASE WHEN Selected' + @GUID + '.UID = @GUID
                                                 THEN NULL
                                                 ELSE @GUID
                                            END
             ' +  @FROMCLAUSE + '
             ' + @WHERECLAUSE + ';';

EXEC sp_executesql @sql, N'@FROMCLAUSE VARCHAR(8000), @UPDATETABLE VARCHAR(50), @GUID VARCHAR(3), @WHERECLAUSE VARCHAR(8000)', @FROMCLAUSE,@UPDATETABLE, @GUID, @WHERECLAUSE; 

END

您可以通过2个更新轻松完成此操作

Update YourTable Set SelectedUID = 'SomeValueThatDoesntExist'
where SelectedID = 'CJ'

Update YourTable Set SelectedUID = 'CJ'
where SelectedID = 'SomeValueThatDoesntExist'

您可以通过2个更新轻松完成此操作

Update YourTable Set SelectedUID = 'SomeValueThatDoesntExist'
where SelectedID = 'CJ'

Update YourTable Set SelectedUID = 'CJ'
where SelectedID = 'SomeValueThatDoesntExist'

假设在一次更新中表中只有两个不同的值,这意味着您不需要一个事务来跨越多个更新

UPDATE
   SomeTable
SET
   SelectedUID = CASE WHEN SelectedUID <> 'CJ' THEN 'CJ' ELSE '' END
或者


假设在一次更新中表中只有两个不同的值,这意味着您不需要一个事务来跨越多个更新

UPDATE
   SomeTable
SET
   SelectedUID = CASE WHEN SelectedUID <> 'CJ' THEN 'CJ' ELSE '' END
或者


另一种方法是第三张桌子

Selections
ID Selection
1  NULL
2  CJ

然后在交换表中链接到它,然后您只需要在选择表中切换。操作数相同,但只更新了两条记录。

另一种方法是使用第三个表

Selections
ID Selection
1  NULL
2  CJ

然后在交换表中链接到它,然后您只需要在选择表中切换。操作数相同,但只更新了两条记录。

此功能应该会有所帮助

CREATE FUNCTION udf_SwapValues
(
@InputStr VARCHAR(5),
@ReplaceStr1 VARCHAR(5),
@ReplaceStr2 VARCHAR(5)
)
RETURNS VARCHAR(5)
AS
BEGIN

    DECLARE @Return VARCHAR(5)
    SELECT @Return = CASE
                 WHEN @InputStr = @ReplaceStr1 THEN @ReplaceStr2
                 WHEN @InputStr = @ReplaceStr2 THEN @ReplaceStr1
                 ELSE @InputStr
                 END

    -- Return the result of the function
    RETURN @Return

END
GO
用法:

ID    SelectedUID
------------------
1         
2         
3         CJ
4         
5         
DECLARE @table TABLE (ID INT,
                  SelectedUID VARCHAR(5))
INSERT INTO @table
VALUES  (1, ''),
       (2, ''),
       (3, 'CJ'),
       (4, ''),
       (5, '')

SELECT ID,SelectedUID
FROM @table

--USAGE WITH SELECT

SELECT ID,
      dbo.udf_SwapValues(SelectedUID, 'CJ', '')
FROM @table

--USAGE WITH UPDATE
UPDATE t
SET t.SelectedUID = dbo.udf_SwapValues(t.SelectedUID, 'CJ', '')
FROM @table t

SELECT *
FROM @table

这个功能应该有帮助

CREATE FUNCTION udf_SwapValues
(
@InputStr VARCHAR(5),
@ReplaceStr1 VARCHAR(5),
@ReplaceStr2 VARCHAR(5)
)
RETURNS VARCHAR(5)
AS
BEGIN

    DECLARE @Return VARCHAR(5)
    SELECT @Return = CASE
                 WHEN @InputStr = @ReplaceStr1 THEN @ReplaceStr2
                 WHEN @InputStr = @ReplaceStr2 THEN @ReplaceStr1
                 ELSE @InputStr
                 END

    -- Return the result of the function
    RETURN @Return

END
GO
用法:

ID    SelectedUID
------------------
1         
2         
3         CJ
4         
5         
DECLARE @table TABLE (ID INT,
                  SelectedUID VARCHAR(5))
INSERT INTO @table
VALUES  (1, ''),
       (2, ''),
       (3, 'CJ'),
       (4, ''),
       (5, '')

SELECT ID,SelectedUID
FROM @table

--USAGE WITH SELECT

SELECT ID,
      dbo.udf_SwapValues(SelectedUID, 'CJ', '')
FROM @table

--USAGE WITH UPDATE
UPDATE t
SET t.SelectedUID = dbo.udf_SwapValues(t.SelectedUID, 'CJ', '')
FROM @table t

SELECT *
FROM @table

哇!你发布的新存储过程很可怕!!!您应该查找sql注入。这个程序是完全开放的。我很好奇为什么您有一个名为GUID的变量,它实际上是一个varchar 3。;)我传递给SP的内容非常受控制,因为用户无法影响它,因为它在前端都是“硬编码”的。还有一些用户有char(3)和char(2);)-让我知道,如果你能帮我验证这个可怕的SP:PNo攻击,但这并不能保护你。前端是什么?使用request.form的网站?即便如此,程序本身也是脆弱的。它不起作用的原因是因为所有参数都为空,因为您没有为它们赋值。将exec行更改为该行,它应该可以工作(由于此处的限制,我不得不在@之后添加空格)。EXEC sp_executesql@sql,N'@FROMCLAUSE VARCHAR(8000),@UPDATETABLE VARCHAR(50),@GUID VARCHAR(3),@WHERECLAUSE VARCHAR(8000),@FROMCLAUSE=@FROMCLAUSE,@UPDATETABLE=@UPDATETABLE,@GUID=@GUID,@WHERECLAUSE=@WHERECLAUSE;哇!你发布的新存储过程很可怕!!!您应该查找sql注入。这个程序是完全开放的。我很好奇为什么您有一个名为GUID的变量,它实际上是一个varchar 3。;)我传递给SP的内容非常受控制,因为用户无法影响它,因为它在前端都是“硬编码”的。还有一些用户有char(3)和char(2);)-让我知道,如果你能帮我验证这个可怕的SP:PNo攻击,但这并不能保护你。前端是什么?使用request.form的网站?即便如此,程序本身也是脆弱的。它不起作用的原因是因为所有参数都为空,因为您没有为它们赋值。将exec行更改为该行,它应该可以工作(由于此处的限制,我不得不在@之后添加空格)。EXEC sp_executesql@sql,N'@FROMCLAUSE VARCHAR(8000),@UPDATETABLE VARCHAR(50),@GUID VARCHAR(3),@WHERECLAUSE VARCHAR(8000),@FROMCLAUSE=@FROMCLAUSE,@UPDATETABLE=@UPDATETABLE,@GUID=@GUID,@WHERECLAUSE=@WHERECLAUSE;创建一个标量函数而不是仅仅创建两个update语句似乎有点过分了。标量函数的性能是出了名的差。@SeanLange,op问“在SQL Server中有没有函数或一种简单的方法可以做到这一点?”。然而,是的,我同意UDF在使用不当时会造成巨大的性能瓶颈。然而,看到“用户选择相反对象的快速方法”这一问题,告诉我所讨论的列表不能太大,因此性能甚至可能不在等式中。但是,当快速方法是简单的方法时,为什么要采用缓慢的方法呢?标量函数最大的问题是,在一个小的结果集上,它是正常的。这会让人们看到它在一个地方使用,而在其他地方使用同样的东西,性能会让你的服务器崩溃。我想说的一点是,说“在这种情况下,性能不会成为问题”是不可接受的。让你所有的代码都快一点,你就不必担心了。创建一个标量函数而不是两个update语句似乎有点过分了。标量函数的性能是出了名的差。@SeanLange,op问“在SQL Server中有没有函数或一种简单的方法可以做到这一点?”。然而,是的,我同意UDF在使用不当时会造成巨大的性能瓶颈。然而,看到“用户选择相反对象的快速方法”这一问题,告诉我所讨论的列表不能太大,因此性能甚至可能不在等式中。但是,当快速方法是简单的方法时,为什么要采用缓慢的方法呢?标量函数最大的问题是,在一个小的结果集上,它是正常的。这会让人们看到它在一个地方使用,而在其他地方使用同样的东西,性能会让你的服务器崩溃。我想说的一点是,说“在这种情况下,性能不会成为问题”是不可接受的。让你所有的代码都快一点,你就不用担心了。