标签: sql-server

表扫描如何返回比表中更多的行?

我对具有错误统计数据和碎片索引的数据库进行了复杂查询.我感到困惑的是,当我检查一个实际的查询计划时,我从一个具有23 K行的表上的表扫描得到54 M行.查询计划远远超过了这个表与自身相连(23 K中只有260 K行).这怎么可能?

运行一些其他查询或重建索引和统计数据会使这一点消失,我只是想了解为什么会发生这种情况.

我已经使用SQL 2005和SQL 2008 R2在同一数据库的还原上重现了这一点.

更新:是的,这是一个实际的计划.行数是20039(如上所述,不是23 K).这是最右边的节点之一.

sql-server sql-execution-plan

7
推荐指数
1
解决办法
1268
查看次数

在T-SQL中的case语句中

可以在mssql的case语句中使用break命令吗?

因为条件是验证表达式GO,而不是做下一个CASE的转换.ssip_miktar是5,ssip_teslim_miktar是0,S74MIKTAR是5

update set ssip_teslim_miktar= ssip_teslim_miktar+
CASE WHEN ssip_miktar<@S74MIKTAR AND ssip_teslim_miktar=0 THEN @S74MIKTAR-ssip_miktar
WHEN ssip_miktar<@S74MIKTAR AND ssip_teslim_miktar>0 THEN @S74MIKTAR-(ssip_miktar+ssip_teslim_miktar) 
WHEN ssip_miktar=@S74MIKTAR AND ssip_teslim_miktar=0 THEN @S74MIKTAR 
WHEN ssip_miktar=@S74MIKTAR AND ssip_teslim_miktar>0 THEN @S74MIKTAR-ssip_teslim_miktar
 WHEN ssip_miktar>@S74MIKTAR AND ssip_teslim_miktar=0 THEN @S74MIKTAR
 WHEN ssip_miktar>@S74MIKTAR AND ssip_teslim_miktar>0 THEN @S74MIKTAR  
END,
@S74MIKTAR=@S74MIKTAR-CASE 
         WHEN  ssip_miktar<@S74MIKTAR AND ssip_teslim_miktar=0 THEN @S74MIKTAR-ssip_miktar
         WHEN  ssip_miktar<@S74MIKTAR AND ssip_teslim_miktar>0 THEN @S74MIKTAR-(ssip_miktar+ssip_teslim_miktar)
         WHEN  ssip_miktar=@S74MIKTAR AND ssip_teslim_miktar=0 THEN @S74MIKTAR
         WHEN  ssip_miktar=@S74MIKTAR AND ssip_teslim_miktar>0 THEN @S74MIKTAR-ssip_teslim_miktar
         WHEN  ssip_miktar>@S74MIKTAR AND ssip_teslim_miktar=0 THEN @S74MIKTAR
         WHEN  ssip_miktar>@S74MIKTAR AND …
Run Code Online (Sandbox Code Playgroud)

sql t-sql sql-server

7
推荐指数
3
解决办法
2万
查看次数

无法将SQLCLR程序集添加到数据库,Msg 300

我在将SQLCLR程序集添加到数据库时遇到了问题,但是我的同事没有问题.虽然我们确实有不同级别的访问权限,但我们无法弄清楚为什么我收到了错误消息.

这是我的代码:

USE [mydatabase]
GO

CREATE ASSEMBLY [My.Assembly]
AUTHORIZATION [dbo]
FROM 'C:\Program Files\MyStuff\My.Assembly.dll'
WITH PERMISSION_SET = UNSAFE
GO
Run Code Online (Sandbox Code Playgroud)

这是我的错误:

Msg 300,Level 14,State 1,Line 3
UNSAFE ASSEMBLY权限被拒绝对象'服务器',数据库'master'.

思考?

sql-server permissions sqlclr sql-server-2008

7
推荐指数
2
解决办法
5180
查看次数

SQL Server:如何检查数据库中是否存在Windows用户,但是使用不同的用户名

我试图通过SQL Server 2005/2008中的T-SQL脚本创建用户.我运行以下SQL来检查用户是否存在,如果不存在则创建用户:

IF NOT EXISTS (SELECT * 
               FROM   sys.database_principals 
               WHERE  name = N'MyDomain\MyUser') 
  BEGIN 
      CREATE USER [MyDomain\MyUser] FOR LOGIN [MyDomain\MyUser] WITH default_schema=[dbo]; 

      SELECT 1; 
  END 
ELSE 
  BEGIN 
      SELECT 0; 
  END  
Run Code Online (Sandbox Code Playgroud)

不幸的是,当Windows帐户MyDomain\MyUser已经在数据库中但名称不同时,这不起作用.一个例子是,如果MyDomain\MyUser是创建数据库的帐户,那么它将已经在dbo用户下的数据库中.在这种情况下,我收到以下错误:

消息15063,级别16,状态1,行1登录已具有不同用户名下的帐户.

如何检查Windows用户MyDomain\MyUser是否已经是数据库中的用户,即使它是在不同的用户名下?

sql t-sql sql-server sql-server-2005 sql-server-2008

7
推荐指数
1
解决办法
9173
查看次数

返回id并拆分逗号分隔值的SQL语句

我有一个包含以下数据的表:

NodeId ExternalIds
50     601
56     700,701

如何编写一个SQL语句,它拆分ExternalIds-column并返回:

NodeId ExternalIds
50     601
56     700
56     701

我找到了很多用户定义的函数和过程,它们将一个字符串拆分成一个表,但我无法让它们中的任何一个工作

编辑

create table #tmpTable (NodeId int, ExternalIds varchar(50))
insert into #tmpTable (NodeId,ExternalIds) values (50, '600')
insert into #tmpTable (NodeId,ExternalIds) values (56, '700,701')

select NodeId, 
    (SELECT * FROM [dbo].[SplitString](select * from #tmpTable,',') where NodeId=56)from #tmpTable)
where NodeId=56
drop table #tmpTable

其中SplitString基于以下内容:

SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO

Create FUNCTION [dbo].[SplitString] 
(
    -- Add the parameters for the function here
    @myString varchar(500),
    @deliminator …

sql-server

7
推荐指数
1
解决办法
4221
查看次数

有没有办法在SQL Server游标中使用参数?

我在数据库中有一个父子关系.我需要做的是遍历父查询,并使用父的主键,得到它的孩子.我遇到的问题是我需要使用参数化游标(传入密钥)来执行此操作.

在SQL Server中是否有这样的东西或模仿这个?我试过这样做,但它不起作用:

DECLARE @value   VARCHAR(20);
DECLARE @someKey NUMERIC(19,0);

DECLARE main_curs 
CURSOR FOR SELECT value FROM someTable where key = @someKey;

SET @someKey = 12345;

OPEN main_curs
FETCH NEXT FROM main_curs INTO @value;
CLOSE main_curs
DEALLOCATE main_curs
Run Code Online (Sandbox Code Playgroud)

但似乎它没有接我设置@someKey.

任何有关这方面的帮助将不胜感激.谢谢!

UPDATE

我应该包含更多信息,因为我让这个例子看起来太简单了.我有多个需要使用的@someKey值.如前所述,我有亲子关系,最多可以有6个孩子.所以我得到一个父母列表,它是各自的列,并迭代它.在WHILE-LOOP中,我想从父级获取主键并调用另一个游标来获取子信息(返回不同的列).所以我会对子游标进行多次调用,并设置不同的@someKey值.希望有道理.

sql t-sql sql-server cursor

7
推荐指数
2
解决办法
4万
查看次数

如何在Firebird中使用交易?

在MS SQL Server中,我可以轻松地将多个insert语句放入事务中,如下所示:

begin tran
insert into mytable values (1, 2, 3)
insert into mytable values (4, 5, 6)
commit tran
Run Code Online (Sandbox Code Playgroud)

我试图在Firebird中做同样的事情,但我无法弄清楚语法.谷歌搜索"Firebird事务语法"返回没有任何用处.我已经发现足够知道存在事务支持,但没有关于如何正确使用它的示例.

所以我想我也可以问这里.有谁知道如何使用Firebird数据库的多个插入来编写事务?

sql database sql-server firebird transactions

7
推荐指数
2
解决办法
2万
查看次数

如何将nvarchar解码为文本(SQL Server 2008 R2)?

我有一个SQL Server 2008 R2表与nvarchar(4000)字段.

存储此表的数据看起来像

'696D616765206D61726B65643A5472'

要么

'303131' ("011").

我看到每个char都编码为十六进制.

如何从表中读取这些数据?我不想写解码功能,我的意思是存在更简单的方法.

PS抱歉我的英文.

sql-server encoding nvarchar decoding sql-server-2008

7
推荐指数
1
解决办法
3469
查看次数

管理数据库迁移:脚本与工具

我们的项目有大约20个开发人员,但我们的应用程序相对较少使用数据库.我们有大约5个数据库的集合,所有这些数据库都非常小,每个数据库的表少于20个,其中没有数百个行或任何大的数据库.

关于如何随着时间的推移管理数据库的演变,我们有两个选项:

  • 某种工具.目前,我们正在使用Visual Studio数据库项目,其中包含模式的当前定义,并查看参考数据库以生成diff脚本.然后,我们使用此diff脚本使参考数据库保持最新.
  • 使用版本脚本从基线构建数据库.脚本手动放置在源代码管理中.将数据从旧列/表移动到新数据的任何数据迁移都将成为这些脚本的一部分.在某个地方会有一个版本记录在DB中,升级会运行DB版本和当前版本之间的所有脚本.

第二个选项似乎被广泛使用,我在这里找到了一个深入的讨论:http://odetocode.com/blogs/scott/archive/2008/01/31/versioning-databases-the-baseline.aspx

我们目前遇到的问题是我们无法访问我们的生产数据库.这意味着要创建一个发布包,我们必须将Production的备份还原到另一个位置,针对该引用数据库生成差异并将脚本提供给生产数据库团队.因此,我们的生产发布与我们的其他环境不同.

这使得运行版本化脚本的想法很吸引人,因为我们在所有环境中使用相同的脚本,并且在部署中没有临时工作(例如,手动恢复prod到参考DB).但鉴于我们有这么小规模的数据库情况,我觉得我们几乎不可能成为数据库工具的困难案例.我们想要的是尽可能简单易懂的东西.

RedGate套件之类的工具是否适用于这种情况,或者我们应该使用版本化脚本吗?成本并不是一个问题,它更多的是创建一个成功的坑,维护和部署数据库是尽可能基本和自动化.

database sql-server deployment

7
推荐指数
1
解决办法
6717
查看次数

解析字符串SQL

我在MSSQL中有这么长的字符串,我需要I值.

我代表发票,A代表金额,D代表日期

I = 940; A = 29.5; d = 20090901 | I = 941; A = 62.54; d = 20090910 | I = 942; A = 58.99; d = 20091005 | I = 954; A = 93.45; d = 20091201 | I = 944; A = 96.76; d = 20091101 | I = 946; A = 52.5; d = 20091101 | I = 943; A = 28.32; d = 20091101 | I = 945; A = 52.5; d = …

sql t-sql sql-server

7
推荐指数
1
解决办法
4809
查看次数