AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / user-4416

Scott Chamberlain's questions

Martin Hope
Scott Chamberlain
Asked: 2016-08-18 07:33:15 +0800 CST

是否可以从 SQL Server 中提取(而不是重置)sa 或其他密码?

  • 0

首先,我不需要重设 SA 密码,我知道该怎么做,并且本网站和其他地方有大量资源提供详细的分步教程。

我们在客户端现场设置了 SQL 服务器,我遇到的问题是第 3 方公司正在使用我们自己的服务登录名登录服务器并进行数据挖掘和数据推送。我们正在努力阻止这种行为(我知道这是一个不可能实现的目标,但我正在努力让其他人相信这一事实)。

我们已经弄清楚他们目前是如何获得我们的登录信息的,并将解决这个问题,但我想知道的是:是否有任何已知的工具或过程可以从 sql server 实例(无论是离线的)中“提取”登录密码攻击或通过拦截和窥探有效连接)?

我认为可能有办法做到这一点,但管理层希望证明它可以做到。

有谁知道可以使用的任何工具或流程集,以便我可以向管理层展示概念证明?

sql-server security
  • 2 个回答
  • 188 Views
Martin Hope
Scott Chamberlain
Asked: 2014-10-03 07:50:05 +0800 CST

当几乎所有列都是唯一索引的一部分时选择聚集键

  • 1

我正在创建下表

CREATE TABLE dbo.COMM_SHELF_BLOCK_ACCESS
    (
    KeyId uniqueidentifier NOT NULL ROWGUIDCOL CONSTRAINT DF_COMM_SHELF_BLOCK_ACCESS_KeyId default NEWSEQUENTIALID(),
    EmployeeGuid uniqueidentifier NOT NULL,
    PracticeVid smallint NOT NULL,
    ShelfGuid uniqueidentifier NOT NULL,
    CONSTRAINT PK_COMM_SHELF_BLOCK_ACCESS PRIMARY KEY CLUSTERED (KeyId)
    )  ON [PRIMARY]
GO

CREATE UNIQUE NONCLUSTERED INDEX UX_COMM_SHELF_BLOCK_ACCESS 
    ON dbo.COMM_SHELF_BLOCK_ACCESS (ShelfGuid, EmployeeGuid, PracticeVid)

GO

我从不KeyId在我的程序中使用它,它仅用于合并复制。我的应用程序将使用此表的最常见查询是

--This will be passed in parameters to the SP
declare @practiceVid smallint = 0
declare @employeeGuid uniqueidentifier = 'C413A410-E13E-4647-9D68-2A38FBC45906'

--actual query
select * from COMM_SHELF
where COMM_SHELF.SHELF_GUID not in 
    (
        select ShelfGuid 
        from COMM_SHELF_BLOCK_ACCESS 
        where EmployeeGuid = @employeeGuid 
            and PracticeVid = @practiceVid
    )

我的新表的索引结构是否合适?在我看来最重要的是我正在复制那个唯一索引中的几乎整个表。我做的另一个想法是像下面这样构造表格

CREATE TABLE dbo.COMM_SHELF_BLOCK_ACCESS
    (
    KeyId uniqueidentifier NOT NULL ROWGUIDCOL CONSTRAINT DF_COMM_SHELF_BLOCK_ACCESS_KeyId default NEWSEQUENTIALID(),
    EmployeeGuid uniqueidentifier NOT NULL,
    PracticeVid smallint NOT NULL,
    ShelfGuid uniqueidentifier NOT NULL,
    CONSTRAINT PK_COMM_SHELF_BLOCK_ACCESS PRIMARY KEY NONCLUSTERED (KeyId),
    CONSTRAINT CK_COMM_SHELF_BLOCK_ACCESS UNIQUE CLUSTERED (ShelfGuid, EmployeeGuid, PracticeVid)
    )  ON [PRIMARY]
GO

使这 3 列成为我对聚集键感兴趣的列。然而,这违反了我到处阅读的“保持聚簇键窄”和“保持聚簇键顺序”指南。

这些方法中的哪一个是实现它的正确方法?如果两者都不正确,请告诉我处理此问题的正确方法是什么。

sql-server-2008 index
  • 1 个回答
  • 85 Views
Martin Hope
Scott Chamberlain
Asked: 2014-04-03 23:24:27 +0800 CST

每个查询计划统计数据都表明我的查询应该更快,但事实并非如此

  • 4

我的情况有点奇怪。我有两个产生相同结果的查询,根据 SSMS 和 SQL Sentry Plan Explorer,第一个查询应该花费 95%,第二个查询应该花费 5%。但是,第一个查询在 132 毫秒内完成,第二个查询在 8,531 毫秒内完成。

--query 1
with results as(
SELECT
      P.[patient_guid]
      ,P.[client_guid]
      ,P.[patient_account_id]
      ,C.[database_guid]
      ,P.[patient_name]   
      ,P.[rabies_tag_number]
      ,P.[rabies_serial_number]
      ,P.[rabies_brand_name]
      ,P.[species]     
      ,P.[breed] 
      ,P.[coat_color]
      ,P.[sex]
      ,P.[birthdate]
      ,P.[latest_visit]
      ,P.[first_visit]
      ,P.[maturity_code]
      ,P.[medical_alert]
      ,P.[chronic_ailment]
      ,P.[continuous_medication]
      ,P.[weight]
      ,P.[doctor_preference]
      ,P.[tattoo_number]
      ,P.[avid_chip_number]
      ,P.[comment]
      ,P.[special_instructions]
      ,P.[health_plan_name]
      ,P.[deleted]
      ,P.[has_lab_results]
      ,P.[trainer_id]
      ,P.[stable_id]
      ,C.[first_name]
      ,C.[last_name]
      ,P.[active]
      ,P.[deceased_date]

      ,row_number() over (order by patient_name) as rownumber
      ,row_number() over (order by patient_name DESC) as totalRows
  FROM [patients] P

  inner join clients C on P.client_guid = C.client_guid
  where C.database_guid = @DatabaseGuid and P.patient_name like '%'+@SearchText+'%')

  select patient_guid, client_guid, patient_account_id, database_guid, patient_name, rabies_tag_number, rabies_serial_number, rabies_brand_name, species, 
         breed, coat_color, sex, birthdate, latest_visit, first_visit, maturity_code, medical_alert, chronic_ailment, continuous_medication, weight, 
         doctor_preference, tattoo_number, avid_chip_number, comment, special_instructions, health_plan_name, deleted, has_lab_results, first_name, last_name, trainer_id, stable_id, active, deceased_date,
         totalRows + rownumber - 1 as total from results where rownumber >= @PageSize * @PageNumber + 1 and rownumber <= @PageSize * @PageNumber + 1+ @PageSize - 1
         ORDER BY patient_name ASC

--query 2
with results as(
SELECT
      P.[patient_guid]
      ,P.[client_guid]
      ,P.[patient_account_id]
      ,C.[database_guid]
      ,P.[patient_name]   
      ,P.[rabies_tag_number]
      ,P.[rabies_serial_number]
      ,P.[rabies_brand_name]
      ,P.[species]     
      ,P.[breed] 
      ,P.[coat_color]
      ,P.[sex]
      ,P.[birthdate]
      ,P.[latest_visit]
      ,P.[first_visit]
      ,P.[maturity_code]
      ,P.[medical_alert]
      ,P.[chronic_ailment]
      ,P.[continuous_medication]
      ,P.[weight]
      ,P.[doctor_preference]
      ,P.[tattoo_number]
      ,P.[avid_chip_number]
      ,P.[comment]
      ,P.[special_instructions]
      ,P.[health_plan_name]
      ,P.[deleted]
      ,P.[has_lab_results]
      ,P.[trainer_id]
      ,P.[stable_id]
      ,C.[first_name]
      ,C.[last_name]
      ,P.[active]
      ,P.[deceased_date]
  FROM [patients] P
  inner join clients C on P.client_guid = C.client_guid
  where C.database_guid = @DatabaseGuid and P.patient_name like '%'+@SearchText+'%')
select results.*, (select count(*) from results) as total
from results
ORDER BY patient_name ASC, patient_guid
OFFSET (@PageSize * @PageNumber) ROWS
FETCH NEXT @PageSize ROWS ONLY;

查询 1 计划 (单击图像查看大图,或单击此处查看 XML)
在此处输入图像描述

查询 2 计划 (单击图像查看大图,或在此处查看 XML)在此处输入图像描述

SQL Sentry Plan Explorer 的输出

+------------+------------+---------+--------+------ ------+--------+--------+------------+-------- -+------------+------------+----------------+-- ----------------------+
| 声明 | 估算成本 | 持续时间 | 中央处理器 | 估算 CPU 成本 | 阅读 | 写 | 估算 IO 成本 | 东行 | 实际行 | 关键查找 | 排序操作 | 哈希匹配操作 |
+------------+------------+---------+--------+------ ------+--------+--------+------------+-------- -+------------+------------+----------------+-- ----------------------+
| 查询 1 | 94.90% | 132 | 140 | 66.80% | 27,187 | 96.10% | 9 | 50 | 1 | 4 | 0 | |
| 查询 2 | 5.10% | 8,525 | 8,531 | 33.20% | 636,973 | 3.90% | 100 | 50 | 1 | 0 | 1 | |
+------------+------------+---------+--------+------ ------+--------+--------+------------+-------- -+------------+------------+----------------+-- ----------------------+

来自的输出SET STATISTICS IO ON

(50 行受影响)
表“患者”。扫描计数 1464,逻辑读取 27172,物理读取 0,预读读取 0,lob 逻辑读取 200,lob 物理读取 0,lob 预读读取 0。
表“客户”。扫描计数 1,逻辑读取 15,物理读取 0,预读读取 0,lob 逻辑读取 0,lob 物理读取 0,lob 预读读取 0。

(50 行受影响)
表“客户”。扫描计数 1,逻辑读取 263329,物理读取 0,预读读取 0,lob 逻辑读取 0,lob 物理读取 0,lob 预读读取 0。
表“患者”。扫描计数 2,逻辑读取 480565,物理读取 12,预读读取 32362,lob 逻辑读取 200,lob 物理读取 0,lob 预读读取 0。
表“工作台”。扫描计数 0,逻辑读取 0,物理读取 0,预读读取 0,lob 逻辑读取 0,lob 物理读取 0,lob 预读读取 0。

我最近对数据库所做的事情:

我运行了 Database Engine Tuning Advisor 并让它查看我的计划缓存(已经建立了几周)并添加了它推荐的所有统计信息和索引。之后,我UPDATE STATISTICS在 bothclients和patientsoption上都做了一个FULLSCAN。之后,我跑去DBCC FREEPROCCACHE使用旧的统计数据和索引清除所有旧计划。然后,我运行了几次查询以缓存数据,并让任何需要编译的查询计划进行编译。毕竟,我在 SQL Sentry Plan Explorer 中运行查询以获取我在此处列出的数字。

为什么 SQL 认为第一个查询要贵得多,为什么我执行的类似重写做得更好时我的第二个查询花费的时间要长得多?

sql-server sql-server-2012
  • 1 个回答
  • 413 Views
Martin Hope
Scott Chamberlain
Asked: 2014-04-02 06:22:54 +0800 CST

差异数据库(不是备份)

  • 3

当经常使用虚拟机时,拥有一个基本的只读 VM 然后有几个较小的 VM 使用该较大的 VM 作为基础并将它们的更改写入它们自己的可写副本可能非常有用。

Microsoft Sql Server 中有类似的东西吗?

我所处的情况是我们托管了我们产品的演示副本,我们的客户可以连接大约 30 天左右。当我们创建模拟账户时,我们必须创建程序使用的基础数据库的新副本,并让软件指向该副本。每个图像略超过 2GB,但平均而言,演示用户只会更改数据库中大约 100MB 的数据。

我想做的是有一个只读数据库作为基础,然后让演示数据库创建一个“差异数据库”并将其数据和日志信息写到该差异数据库中。这可能吗?我一直在搜索 MSDN 文档,但我还没有找到任何东西,不幸的是谷歌搜索已经相当无用,因为搜索Sql server differential database被所有关于做差异备份的页面污染了(做Sql server differential database -backup也没有返回任何有用的结果,我得到的只是有关差异部署脚本的信息)。

sql-server sql-server-2012
  • 2 个回答
  • 205 Views
Martin Hope
Scott Chamberlain
Asked: 2014-03-21 07:59:51 +0800 CST

SHOWPLAN 不显示警告,但“包含执行计划”会显示相同的查询

  • 3

我在 SSMS 中运行以下查询,它在“包含执行计划”窗口中向我显示警告

select CLIENT_GUID, PMT_AMOUNT, DATE_COMPLETED
from
(
    select
     payment.CLIENT_GUID, payment.PMT_AMOUNT, hist.DATE_COMPLETED, ROW_NUMBER() over (partition by payment.client_guid order by payment.deposit_date desc, payment.create_date_time  desc) rn
     from 
     trnPMT payment WITH (NOLOCK)
     inner join trnHistory hist WITH (NOLOCK) on payment.TRANS_GUID = hist.TRANS_GUID
     Where 
     payment.REVISED = 0 and
     payment.mpmt_guid <> '00000000-0000-0000-0000-000000000000'
) pmt
where pmt.rn = 1

警告是“操作员在执行期间使用 tempdb 以溢出级别 1 溢出数据”

在此处输入图像描述
(在此处规划 XML)

我去调查了更多,但在他们的版本中既没有做SET SHOWPLAN_ALL ON也没有SET SHOWPLAN_XML ON显示警告。

显示计划_全部:

+------------------------------------------------ ---------------------------------------------- ---------------------------------------------- ---------------------------------------------- ---------------------------------------------- ------------------------------------------------+ ------+--------+--------+--------------------+ ----------------------+------------------------ ---------------------------------------------- ---------------------------------------------- ---------------------------------------------- ---------------------------------------------- ------------------+---------------------------- ---------------------------------------------- ------------------------------------------------+ --------------+------------+------------+-------- ----+----------------+------------------------ -------------------------------------------------------- ---------------------------------------------- ----------+------------+---------+--------+------ --------------+
| 文本 | 状态 | 节点编号 | 家长 | 物理操作 | 逻辑运算 | 争论 | 定义值 | 估计行 | 估计IO | 预估CPU | 平均行大小 | 总子树成本 | 输出列表 | 警告 | 类型 | 并行| 估计执行 |
+------------------------------------------------ ---------------------------------------------- ---------------------------------------------- ---------------------------------------------- ---------------------------------------------- ------------------------------------------------+ ------+--------+--------+--------------------+ ----------------------+------------------------ ---------------------------------------------- ---------------------------------------------- ---------------------------------------------- ---------------------------------------------- ------------------+---------------------------- ---------------------------------------------- ------------------------------------------------+ --------------+------------+------------+-------- ----+----------------+------------------------ -------------------------------------------------------- ---------------------------------------------- ----------+------------+---------+--------+----- --------------+
| 选择 CLIENT_GUID、PMT_AMOUNT、日期_完成 | | | | | | | | | | | | | | | | | |
| 来自 | | | | | | | | | | | | | | | | | |
| ( | | | | | | | | | | | | | | | | |
| 选择 | | | | | | | | | | | | | | | | | |
| payment.CLIENT_GUID, payment.PMT_AMOUNT, hist.DATE_COMPLETED, ROW_NUMBER() over (partition by payment.client_guid order by payment.deposit_date desc, payment. create_date_time desc) rn | | | | | | | | | | | | | | | | |
| 来自 | | | | | | | | | | | | | | | | | |
| trnPMT 支付 WITH (NOLOCK) | | | | | | | | | | | | | | | | | |
| inner join trnHistory hist WITH (NOLOCK) on payment.TRANS_GUID = hist. TRANS_GUID | | | | | | | | | | | | | | | | | |
| 在哪里 | | | | | | | | | | | | | | | | | |
| 支付。修订 = 0 和 | | | | | | | | | | | | | | | | | |
| payment.mpmt_guid '00000000-0000-0000-0000-000000000000' | | | | | | | | | | | | | | | | | |
| ) 下午 | | | | | | | | | | | | | | | | | |
| 其中 pmt.rn = 1 | 1 | 1 | 0 | 空 | 空 | 1 | 空 | 9283.128 | 空 | 空 | 空 | 40. 03822 | 空 | 空 | 选择 | 0 | 空 |
| |--过滤器(哪里:([Expr1004]=(1))) | 1 | 2 | 1 | 过滤器 | 过滤器 | 其中:([Expr1004]=(1))| 空 | 9283.128 | 0 | 0.09364839 | 39 | 40.03822 | [付款].[CLIENT_GUID], [付款].[PMT_AMOUNT], [历史].[DATE_COMPLETED] | 空 | 计划行 | 0 | 1 |
| |--序列项目(DEFINE:([Expr1004]=row_number)) | 1 | 3 | 2 | 序列项目 | 计算标量 | 定义:([Expr1004]=row_number) | [Expr1004]=行号 | 195100.8 | 0 | 0.01560807 | 47 | 39.94458 | [付款].[CLIENT_GUID], [付款].[PMT_AMOUNT], [历史].[DATE_COMPLETED], [Expr1004] | 空 | 计划行 | 0 | 1 |
| |--段| 1 | 4 | 3 | 段 | 段 | [付款].[CLIENT_GUID] | 空 | 195100.8 | 0 | 0.003902016 | 47 | 39.92897 | [付款].[CLIENT_GUID], [付款].[DEPOSIT_DATE], [付款].[PMT_AMOUNT], [付款].[CREATE_DATE_TIME], [hist].[DATE_COMPLETED], [Segment1005] | 空 | 计划行 | 0 | 1 |
| |--排序(排序方式:([付款]。[CLIENT_GUID] ASC,[付款]。[DEPOSIT_DATE] DESC,[付款]。[CREATE_DATE_TIME] DESC))| 1 | 5 | 4 | 排序 | 排序 | ORDER BY:([payment].[CLIENT_GUID] ASC, [payment].[DEPOSIT_DATE] DESC, [payment].[CREATE_DATE_TIME] DESC) | 空 | 195100.8 | 0.01126126 | 15.73772 | 55 | 39.92507 | [付款].[CLIENT_GUID], [付款].[DEPOSIT_DATE], [付款].[PMT_AMOUNT], [付款].[CREATE_DATE_TIME], [hist].[DATE_COMPLETED] | 空 | 计划行 | 0 | 1 |
| |--Hash Match(Inner Join, HASH:([payment].[TRANS_GUID])=([hist].[TRANS_GUID]), RESIDUAL:([TestDb].[dbo].[trnHistory].[TRANS_GUID] as [hist].[TRANS_GUID]=[TestDb].[dbo].[trnPMT].[TRANS_GUID] as [payment].[TRANS_GUID])) | 1 | 6 | 5 | 哈希匹配 | 内部加入 | HASH:([payment].[TRANS_GUID])=([hist].[TRANS_GUID]), RESIDUAL:([TestDb].[dbo].[trnHistory].[TRANS_GUID] as [hist].[TRANS_GUID]=[ TestDb].[dbo].[trnPMT].[TRANS_GUID] 作为[payment].[TRANS_GUID]) | 空 | 195100.8 | 0 | 14.81137 | 55 | 24.17609 | [付款].[CLIENT_GUID], [付款].[DEPOSIT_DATE], [付款].[PMT_AMOUNT], [付款].[CREATE_DATE_TIME], [hist].[DATE_COMPLETED] | 空 | 计划行 | 0 | 1 |
| |--聚簇索引扫描(OBJECT:([TestDb].[dbo].[trnPMT].[imp_clpk_trnPMT] AS [payment]), WHERE:([TestDb].[dbo].[trnPMT].[REVISED] as [payment].[REVISED]=(0) AND [TestDb].[dbo].[trnPMT].[MPMT_GUID] 作为 [payment].[MPMT_GUID]{guid'00000000-0000-0000-0000-000000000000'}) ) | 1 | 7 | 6 | 聚簇索引扫描 | 聚簇索引扫描 | 对象:([TestDb].[dbo].[trnPMT].[imp_clpk_trnPMT] AS [payment]), WHERE:([TestDb].[dbo].[trnPMT].[REVISED] as [payment].[REVISED] =(0) 和 [TestDb].[dbo].[trnPMT].[MPMT_GUID] 作为 [payment].[MPMT_GUID]{guid'00000000-0000-0000-0000-000000000000'}) | [付款].[TRANS_GUID], [付款].[CLIENT_GUID], [付款].[DEPOSIT_DATE], [付款].[PMT_AMOUNT], [付款].[CREATE_DATE_TIME] | 231167.7 | 6.566088 | 0.2730604 | 80 | 6.839149 | [支付]。[TRANS_GUID],[付款]。[CLIENT_GUID],[付款]。[DEPOSIT_DATE],[付款]。[PMT_AMOUNT],[付款]。[CREATE_DATE_TIME] | 空 | 计划行 | 0 | 1 |
| |--索引扫描(OBJECT:([TestDb].[dbo].[trnHistory].[IX_trnHistory_DATE_COMPLETED_TRANS_GUID_TRANS_NUMBER] AS [hist])) | 1 | 8 | 6 | 索引扫描 | 索引扫描 | 对象:([TestDb].[dbo].[trnHistory].[IX_trnHistory_DATE_COMPLETED_TRANS_GUID_TRANS_NUMBER] AS [hist]) | [历史].[TRANS_GUID], [历史].[DATE_COMPLETED] | 503270 | 1.753495 | 0.553754 | 31 | 2.307249 | [历史].[TRANS_GUID],[历史]。[DATE_COMPLETED] | 空 | 计划行 | 0 | 1 |
+------------------------------------------------ ---------------------------------------------- ---------------------------------------------- ---------------------------------------------- ---------------------------------------------- ------------------------------------------------+ ------+--------+--------+--------------------+ ----------------------+------------------------ ---------------------------------------------- ---------------------------------------------- ---------------------------------------------- ---------------------------------------------- ------------------+---------------------------- ---------------------------------------------- ------------------------------------------------+ --------------+------------+------------+-------- ----+----------------+------------------------ -------------------------------------------------------- ---------------------------------------------- ----------+------------+---------+--------+----- --------------+

SHOWPLAN_XML:(
在此处输入图像描述
在此处规划 XML)

我是偶然发现了某种错误,还是我做错了什么我应该做不同的事情?

(PS 我知道警告的含义以及如何修复它,我对出现在一个地方而不是另一个地方的警告更感兴趣。)

编辑:
这是“关于”帮助页面中我的 SSMS 的版本信息。

Microsoft SQL Server 管理工作室:11.0.3128.0
Microsoft Analysis Services 客户端工具:11.0.3128.0
Microsoft 数据访问组件 (MDAC):6.3.9600.16384
微软 MSXML:3.0 4.0 6.0
微软 Internet Explorer:9.11.9600.16521
微软 .NET 框架:4.0.30319.34011
操作系统:6.3.9600

我正在针对数据库引擎版本运行11.0.3128

sql-server sql-server-2012
  • 1 个回答
  • 893 Views
Martin Hope
Scott Chamberlain
Asked: 2014-03-19 13:23:15 +0800 CST

MERGE 最佳实践的说明

  • 6

我只是想从“优化 MERGE 语句性能”页面询问有关 MSDN 上的某些内容的澄清。

我正在使用一个数据仓库,它从许多不同的数据库中获取记录并存储数据。我的仓库数据库中的所有表基本上都遵循相同的模式:

CREATE TABLE Foo (
    database_guid UNIQUEIDENTIFIER
    ,FooPk BIGINT
    ,Bar NVARCHAR(20)
    ,Qix NCHAR(10)
    ,CONSTRAINT [PK_Foo] PRIMARY KEY CLUSTERED (
        database_guid ASC
        ,FooPk ASC
        )
    )
GO

CREATE PROCEDURE [iv].[LoadSomeTable] 
    @databaseGUID UNIQUEIDENTIFIER
AS
BEGIN
    SET NOCOUNT ON

    MERGE Foo
    USING #FooStaging AS Source
    ON Foo.FooPk = Source.FooPk AND Foo.database_guid = @databaseGUID
    WHEN MATCHED THEN
        UPDATE SET Bar = Source.Bar
                  ,Qix = Source.Qix
    WHEN NOT MATCHED THEN
        INSERT (database_guid, FooPk, Bar, Qix)
            VALUES (@databaseGUID, FooPk, Bar, Qix);
END
GO

CREATE TABLE #FooStaging (
    FooPk BIGINT
    ,Bar NVARCHAR(20)
    ,Qix NCHAR(10)
    )

--Data gets loaded in to #FooStaging from a C# call to SqlBulkCopy then calls iv.LoadSomeTable

我现在担心的是我刚刚从那个 MSDN 页面上读到了这个声明

仅在 ON<merge_search_condition> 子句中指定用于确定源表和目标表中的数据匹配条件的搜索条件。也就是说,仅指定目标表中与源表的对应列进行比较的列。不要包括与其他值(例如常数)的比较。

读完之后,我认为我的查询错误,我的合并语句应该是

MERGE Foo
USING #FooStaging AS Source
ON Foo.FooPk = Source.FooPk
WHEN MATCHED AND Foo.database_guid = @databaseGUID THEN
    UPDATE SET Bar = Source.Bar
              ,Qix = Source.Qix
WHEN NOT MATCHED THEN
    INSERT (database_guid, FooPk, Bar, Qix)
        VALUES (@databaseGUID, FooPk, Bar, Qix);

但这对我来说“感觉”不正确,因为该database_guid字段是主键的一部分,所以它不应该包含在on? 如果我有它,然后我WHEN MATCHED用 a 上传一个数据库FooPk,1那么我用 aFooPk和另一个不同的数据库上传第二个数据库,@databaseGUID我不确定是否NOT MATCHED会触发(刚刚测试过,它不会)。

哪种方式是使用 MERGE 的正确方式?

sql-server sql-server-2012
  • 1 个回答
  • 2434 Views
Martin Hope
Scott Chamberlain
Asked: 2013-09-04 12:23:23 +0800 CST

简单的更新查询气球 tempdb

  • 1

我正在尝试对 csv 文件中的列进行批量更新,但是当我执行实际更新操作时,我的气球大小超过 20 GB(超过了正在运行tempdb的 SSD 的整个大小)。tempdb

我使用批量复制将 csv 文件加载到具有与目标表匹配的架构的临时表中,然后执行查询

Update [Med_Rec_Entries] 
set [Comments] = [Tmp_Med_Rec_Entries].[Comments] 
from [Tmp_Med_Rec_Entries] 
where [Tmp_Med_Rec_Entries].[ID] = [Med_Rec_Entries].[ID]

这就是 temp db 在大小上爆炸的地方。源表和目标表中都有 1,770,373 行(更新的 ID 关系为 1=1)。

我尝试运行数据库优化顾问,它让我创建了一个新索引,但它没有帮助。我要插入的数据库只是数据迁移的中间步骤,除了其他 csv 导入之外没有其他查询,就像我在这里所做的那样,最后将针对该数据库运行批量导出,因此它没有任何索引或键本身。

这是创建表语句Med_Rec_Entries

CREATE TABLE [dbo].[Med_Rec_Entries](
    [ID] [nvarchar](255) NULL,
    [Patient_ID] [nvarchar](80) NULL,
    [Med_Rec_Code] [nvarchar](20) NULL,
    [Tx_Date_Performed] [nvarchar](254) NULL,
    [Comments] [nvarchar](max) NULL,
    [Staff_Code] [nvarchar](21) NULL,
    [Quantity] [real] NULL,
    [Hide_This_Entry] [bit] NULL,
    [Exclude_From_Printed_History] [bit] NULL,
    [Image_ID] [int] NULL,
    [Remote_Status] [nvarchar](2) NULL,
    [Special_Flag] [nvarchar](20) NULL,
    [Tx_Time_Performed] [nvarchar](254) NULL,
    [Tx_Date_Recorded] [nvarchar](254) NULL,
    [Appended_Comments] [nvarchar](max) NULL,
    [Tx_Time_Recorded] [nvarchar](254) NULL,
    [Entry_Is_Locked] [bit] NULL,
    [Create_User] [nvarchar](21) NULL,
    [Audit_DTS] [nvarchar](20) NULL,
    [Audit_Actor] [nvarchar](21) NULL,
    [vQPixAreax_] [varbinary](max) NULL,
    [Route] [nvarchar](80) NULL,
    [Units] [nvarchar](20) NULL,
    [CFR_Reason_Code] [nvarchar](40) NULL,
    [rpl_Key] [nvarchar](14) NULL,
    [rpl_DateTime] [nvarchar](14) NULL,
    [Medical_Description] [nvarchar](max) NULL,
    [caseID] [int] NULL,
    [Sign_Off_Target] [nvarchar](21) NULL,
    [Sign_Off_Date] [nvarchar](254) NULL,
    [Location_Code] [nvarchar](50) NULL,
    [ACUP_ID] [nvarchar](15) NULL,
    [ExcludeFromWeb] [bit] NULL,
    [SecondarySort] [int] NULL,
    [AutosaveState] [nvarchar](20) NULL,
    [_CommentsAndFindingsText] [nvarchar](max) NULL,
    [NewFormat] [bit] NULL,
    [Temp] [nvarchar](80) NULL,
    [Colour] [nvarchar](20) NULL,
    [PrimaryKey] [nvarchar](200) NULL,
    [Sign_Off_Time] [nvarchar](254) NULL
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]

--From the database engine tuning advisor
CREATE NONCLUSTERED INDEX [_dta_index_Med_Rec_Entries_13_933578364__K1] ON [dbo].[Med_Rec_Entries]
(
    [ID] ASC
)WITH (SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, ONLINE = OFF) ON [PRIMARY]

这是创建表语句Tmp_Med_Rec_Entries

CREATE TABLE [dbo].[Tmp_Med_Rec_Entries](
    [ID] [nvarchar](255) NULL,
    [Comments] [nvarchar](max) NULL
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]

我能做些什么来阻止 tempdb 变得太大?

sql-server sql-server-2005
  • 1 个回答
  • 1676 Views
Martin Hope
Scott Chamberlain
Asked: 2013-04-02 10:12:44 +0800 CST

如何抑制信息性 raiserror 消息

  • 1

我有一个设置脚本调用sp_configure几次来设置一些系统变量,它工作正常但我有以下几个语句

配置选项 '%ls' 从 %ld 更改为 %ld。运行 RECONFIGURE 语句进行安装。

相应地填充变量。在内部我可以看到 sp_configure 正在调用

raiserror(15457,-1,-1, @configname, @prevvalue, @configvalue) with log

当用户运行脚本时,我能做些什么来防止这些信息性消息(对脚本无用,我RECONFIGURE从脚本内部调用)显示在 MSSMS 的消息窗口中?

sql-server error-handling
  • 1 个回答
  • 1297 Views
Martin Hope
Scott Chamberlain
Asked: 2013-01-10 10:17:54 +0800 CST

是否有相当于“OVERRIDING USER VALUE”的 SQL Server

  • 0

在谷歌搜索时,我发现了IBM iSeries的OVERRIDING USER VALUE参数。INSERT

Microsoft SQL Server 2005 或更高版本是否有等效命令允许您插入具有IDENTITY列的表并使用自动分配的值而不是传入的用户值?


在这种情况下,主要目标是帮助说服上级不要让我们停止使用 GUID 作为集群主键(该模式是在 SQL 2000 之前开发的,这是一个不错的想法,而现在它是一个可怕的想法想法)向表中添加标识列并将聚集主键移动到该列并将旧索引转换为非聚集唯一索引。

最大的阻力是:

遗留代码中有很多地方使用诸如Insert into XXXX Select * from YYYY where ...列数根据客户端前端的运行时可调整设置而不同的地方。使用标识列会破坏这些查询,而 GUID 是唯一的并且不会出现问题,并且重写所有查询以使用命名列的工作量太大,因为每个安装的客户端的列名都是可变的。

这就是为什么SET IDENTITY_INSERT ON不是一个选项,因为这将是一个主键列。我希望提出这样的论点,即如果我们可以使用 SQL Server 等价物,OVERRIDING USER VALUE我可以使用类似“我们可以在插入语句中添加这个小部分,我们不需要包含列名”这样的论点。

sql-server sql-server-2005
  • 2 个回答
  • 2669 Views
Martin Hope
Scott Chamberlain
Asked: 2012-12-06 11:19:31 +0800 CST

执行计划在使用 PK 时翻转 Filter 和 Execute Scalar,导致转换失败

  • 3

我有一些数据表,它们是从平面文件源导入的,所以varchar(max)除了FileRecordID它是int保存数据来自平面文件源的行号(并且是导入表的主键)之外的所有数据表。

以下查询完美运行

SELECT *
  FROM [CLIENT]
  left outer join
  (
    select cast(ENTRY_CODE as int) as ENTRY_CODE, ENTRY_DESCRIPTION
    from [ENTRY]
    inner join [TABLE] on [ENTRY].ENTRY_TABLE = [Table].FileRecordID
    where ENTRY_RECD = 'A' and TABLE_RECD = 'A' and TABLE_CODE = 'CLTDISC' and ISNUMERIC(ENTRY_CODE) = 1
  ) as discounts on CLIENT_CLASS = ENTRY_CODE
  where Client_recd = 'A'
  --and client.[FileRecordID] = 10607

我得到了我期望的确切行数,一切都很好。但是,如果我取消注释最后一行,那么我只显示client数据表中 的记录,该记录client.[FileRecordID] = 10607向我报告

将 varchar 值“BK/TN”转换为数据类型 int 时,消息 245、级别 16、状态 1、第 1 行
转换失败。

问题出cast(ENTRY_CODE as int) as ENTRY_CODE在第一个外部联接中。ENTRY可以在 ENTRY_CODE 列中包含文本,但是所有ENTRY_TABLE设置为行号的TABLE记录TABLE_CODE = 'CLTDISC'将始终仅为数字。我执行转换时ENTRY_CODE可能有也可能没有前导 0 和空格,所以我试图让它们格式正确。

在我看来正在发生的事情是添加client.[FileRecordID] = 10607到外部查询导致where在内部查询中转换为 int 之前不评估该子句。

我已经尝试过添加and ISNUMERIC(ENTRY_CODE) = 1到内部和外部查询之类的东西,但它没有任何影响。

  1. 我该如何解决?
  2. 任何人都可以解释发生了什么,以便我了解将来如何避免这种情况吗?

非过滤查询计划执行 在此处输入图像描述

过滤的(非工作)查询计划执行 注意和在此处输入图像描述 的相反顺序Compute ScalarFilter


我尝试过的其他不起作用的东西:

  • 移入内部连接TABLE_CODE = 'CLTDISC'中的on子句。
  • 向查询添加OPTION (FORCE ORDER)了查询提示。

更新:
我找到了一个解决方案,但恕我直言,它非常“hackish”,我真的仍然想要解释如何避免将来发生此类事情以及如何正确执行此操作。

SELECT *
  FROM [CLIENT]
  left outer join
  (
    select ENTRY_CODE, ENTRY_DESCRIPTION
    from [ENTRY]
    inner join [TABLE] on [ENTRY].ENTRY_TABLE = [Table].FileRecordID
    where ENTRY_RECD = 'A' and TABLE_RECD = 'A' and TABLE_CODE = 'CLTDISC' and ISNUMERIC(ENTRY_CODE) = 1
  ) as discounts on CLIENT_CLASS = REPLACE(LTRIM(REPLACE(ENTRY_CODE, '0', ' ')), ' ', '0')
  where Client_recd = 'A'
  and client.[FileRecordID] = 10607
sql-server sql-server-2005
  • 2 个回答
  • 1091 Views
Martin Hope
Scott Chamberlain
Asked: 2012-11-26 17:08:51 +0800 CST

除了附加调试器,“(local)\Instance”和“MyLocalName\Instance”之间是否还有其他区别?

  • 7

当使用 SQL Server 2008 R2 连接到本地 SQL Server 2008 R2 实例(版本 10.50.2500)的 SQL Server Management Studio 时,我知道如果我使用实例名称(local)\sql2008,它将无法将调试器附加到我尝试的任何查询使用错误消息进行调试

无法启动 T-SQL 调试。无法连接到计算机“(本地)”。请求的名称有效,但未找到请求类型的数据。

但是,如果我更改src\sql2008与调试器的连接,则运行愉快。

(local)除了我上面指出的调试器问题之外,让您的连接使用别名还有其他区别吗?

sql-server sql-server-2008-r2
  • 1 个回答
  • 1387 Views
Martin Hope
Scott Chamberlain
Asked: 2012-10-09 14:02:57 +0800 CST

为什么索引 REBUILD 不会减少页数 > 1000 的索引碎片?

  • 4

这是对本网站上现有问题“为什么索引重建不会减少索引碎片? ”的后续行动。该问题的公认答案以及我在互联网上找到的所有其他资源都说,如果您的页数较少,碎片整理将无济于事。当百分比低于 10% 时,我也看到了“它只能这么低”的答案

但是我有 3 个索引的表,所有 3 个索引的页数都 > 1900,并且碎片都在 80% 以上。

这是我运行的查询。

select database_id, object_id, index_id, partition_number, index_type_desc, alloc_unit_type_desc, index_depth, index_level, avg_fragmentation_in_percent, fragment_count, avg_fragment_size_in_pages, page_count  FROM sys.dm_db_index_physical_stats (DB_ID(N'i101600'), 78675378, null, null, null)

SELECT b.name, c.name, a.* FROM sys.dm_db_index_physical_stats (DB_ID(N'i101600'), 78675378, null, null, 'DETAILED') a
inner join sys.tables b on a.object_id = b.object_id
inner join sys.indexes c on a.object_id = c.object_id and a.index_id = c.index_id

print 'Rebuilding'
Alter index all on aahaDXavailables rebuild with (online = off)
print 'Done Rebuilding'

SELECT b.name, c.name, a.* FROM sys.dm_db_index_physical_stats (DB_ID(N'i101600'), 78675378, null, null, 'DETAILED') a
inner join sys.tables b on a.object_id = b.object_id
inner join sys.indexes c on a.object_id = c.object_id and a.index_id = c.index_id

select count(*) as Rows from aahaDXavailables

它的结果


+-------------+------------+----------+------------ ------+--------------------+---------- +-------------+-------------+---------- ---------+----------------+------------------------ -----+------------+
| 数据库ID | object_id | index_id | 分区号 | index_type_desc | alloc_unit_type_desc | 索引深度 | index_level | avg_fragmentation_in_percent | 片段计数 | avg_fragment_size_in_pages | 页数 |
+-------------+------------+----------+------------ ------+--------------------+---------- +-------------+-------------+---------- ---------+----------------+------------------------ -----+------------+
| 32 | 78675378 | 1 | 1 | 聚集索引 | IN_ROW_DATA | 3 | 0 | 87.7104377104377 | 2640 | 1.125 | 2970 |
| 32 | 78675378 | 2 | 1 | 非聚集索引 | IN_ROW_DATA | 3 | 0 | 82.0746132848044 | 1853 | 1.18618456556935 | 2198 |
| 32 | 78675378 | 3 | 1 | 非聚集索引 | IN_ROW_DATA | 3 | 0 | 99.1295442908346 | 1952 | 1.00051229508197 | 1953 |
+-------------+------------+----------+------------ ------+--------------------+---------- +-------------+-------------+---------- ---------+----------------+------------------------ -----+------------+
+------------------+------------------ +-------------+------------+----------+------------ ------+--------------------+---------- +-------------+-------------+---------- ---------+----------------+------------------------ -----+------------+------------------------------- -+--------------+---------+------------ ----------------+--------------------------+------ -----------------+--------------+-- ----------------------+
| 姓名 | 姓名 | 数据库ID | object_id | index_id | 分区号 | index_type_desc | alloc_unit_type_desc | 索引深度 | index_level | avg_fragmentation_in_percent | 片段计数 | avg_fragment_size_in_pages | 页数 | avg_page_space_used_in_percent | 记录计数 | ghost_record_count | version_ghost_record_count | min_record_size_in_bytes | max_record_size_in_bytes | avg_record_size_in_bytes | forwarded_record_count |
+------------------+------------------ +-------------+------------+----------+------------ ------+--------------------+---------- +-------------+-------------+---------- ---------+----------------+------------------------ -----+------------+------------------------------- -+--------------+---------+------------ ----------------+--------------------------+------ -----------------+--------------+-- ----------------------+
| aahaDX 可用 | IX_aahaDXavailables_dxGUID | 32 | 78675378 | 2 | 1 | 非聚集索引 | IN_ROW_DATA | 3 | 0 | 82.0746132848044 | 1853 | 1.18618456556935 | 2198 | 64.311304670126 | 327022 | 0 | 0 | 33 | 33 | 33 | 空 |
| aahaDX 可用 | IX_aahaDXavailables_dxGUID | 32 | 78675378 | 2 | 1 | 非聚集索引 | IN_ROW_DATA | 3 | 1 | 100 | 18 | 1 | 18 | 61.8304423029405 | 2198 | 0 | 0 | 39 | 39 | 39 | 空 |
| aahaDX 可用 | IX_aahaDXavailables_dxGUID | 32 | 78675378 | 2 | 1 | 非聚集索引 | IN_ROW_DATA | 3 | 2 | 0 | 1 | 1 | 1 | 9.09315542377069 | 18 | 0 | 0 | 39 | 39 | 39 | 空 |
| aahaDX 可用 | IX_aahaDXavailables_itemGUID | 32 | 78675378 | 3 | 1 | 非聚集索引 | IN_ROW_DATA | 3 | 0 | 99.1295442908346 | 1952 | 1.00051229508197 | 1953 | 72.3821349147517 | 327022 | 0 | 0 | 33 | 33 | 33 | 空 |
| aahaDX 可用 | IX_aahaDXavailables_itemGUID | 32 | 78675378 | 3 | 1 | 非聚集索引 | IN_ROW_DATA | 3 | 1 | 100 | 16 | 1 | 16 | 61.805819125278 | 1953 | 0 | 0 | 39 | 39 | 39 | 空 |
| aahaDX 可用 | IX_aahaDXavailables_itemGUID | 32 | 78675378 | 3 | 1 | 非聚集索引 | IN_ROW_DATA | 3 | 2 | 0 | 1 | 1 | 1 | 8.08005930318755 | 16 | 0 | 0 | 39 | 39 | 39 | 空 |
| aahaDX 可用 | PK_aahaDX 可用 | 32 | 78675378 | 1 | 1 | 聚集索引 | IN_ROW_DATA | 3 | 0 | 87.7104377104377 | 2640 | 1.125 | 2970 | 80.2371756856931 | 327022 | 0 | 0 | 57 | 57 | 57 | 空 |
| aahaDX 可用 | PK_aahaDX 可用 | 32 | 78675378 | 1 | 1 | 聚集索引 | IN_ROW_DATA | 3 | 1 | 94.4444444444444 | 18 | 1 | 18 | 50.9389671361502 | 2970 | 0 | 0 | 23 | 23 | 23 | 空 |
| aahaDX 可用 | PK_aahaDX 可用 | 32 | 78675378 | 1 | 1 | 聚集索引 | IN_ROW_DATA | 3 | 2 | 0 | 1 | 1 | 1 | 5.53496417099086 | 18 | 0 | 0 | 23 | 23 | 23 | 空 |
+------------------+------------------ +-------------+------------+----------+------------ ------+--------------------+---------- +-------------+-------------+---------- ---------+----------------+------------------------ -----+------------+------------------------------- -+--------------+---------+------------ ----------------+--------------------------+------ -----------------+--------------+-- ----------------------+
重建
完成重建
+------------------+------------------ +-------------+------------+----------+------------ ------+--------------------+---------- +-------------+-------------+---------- ---------+----------------+------------------------ -----+------------+------------------------------- -+--------------+---------+------------ ----------------+--------------------------+------ -----------------+--------------+-- ----------------------+
| 姓名 | 姓名 | 数据库ID | object_id | index_id | 分区号 | index_type_desc | alloc_unit_type_desc | 索引深度 | index_level | avg_fragmentation_in_percent | 片段计数 | avg_fragment_size_in_pages | 页数 | avg_page_space_used_in_percent | 记录计数 | ghost_record_count | version_ghost_record_count | min_record_size_in_bytes | max_record_size_in_bytes | avg_record_size_in_bytes | forwarded_record_count |
+------------------+------------------ +-------------+------------+----------+------------ ------+--------------------+---------- +-------------+-------------+---------- ---------+----------------+------------------------ -----+------------+------------------------------- -+--------------+---------+------------ ----------------+--------------------------+------ -----------------+--------------+-- ----------------------+
| aahaDX 可用 | IX_aahaDXavailables_dxGUID | 32 | 78675378 | 2 | 1 | 非聚集索引 | IN_ROW_DATA | 3 | 0 | 82.0746132848044 | 1853 | 1.18618456556935 | 2198 | 64.311304670126 | 327022 | 0 | 0 | 33 | 33 | 33 | 空 |
| aahaDX 可用 | IX_aahaDXavailables_dxGUID | 32 | 78675378 | 2 | 1 | 非聚集索引 | IN_ROW_DATA | 3 | 1 | 100 | 18 | 1 | 18 | 61.8304423029405 | 2198 | 0 | 0 | 39 | 39 | 39 | 空 |
| aahaDX 可用 | IX_aahaDXavailables_dxGUID | 32 | 78675378 | 2 | 1 | 非聚集索引 | IN_ROW_DATA | 3 | 2 | 0 | 1 | 1 | 1 | 9.09315542377069 | 18 | 0 | 0 | 39 | 39 | 39 | 空 |
| aahaDX 可用 | IX_aahaDXavailables_itemGUID | 32 | 78675378 | 3 | 1 | 非聚集索引 | IN_ROW_DATA | 3 | 0 | 99.1295442908346 | 1952 | 1.00051229508197 | 1953 | 72.3821349147517 | 327022 | 0 | 0 | 33 | 33 | 33 | 空 |
| aahaDX 可用 | IX_aahaDXavailables_itemGUID | 32 | 78675378 | 3 | 1 | 非聚集索引 | IN_ROW_DATA | 3 | 1 | 100 | 16 | 1 | 16 | 61.805819125278 | 1953 | 0 | 0 | 39 | 39 | 39 | 空 |
| aahaDX 可用 | IX_aahaDXavailables_itemGUID | 32 | 78675378 | 3 | 1 | 非聚集索引 | IN_ROW_DATA | 3 | 2 | 0 | 1 | 1 | 1 | 8.08005930318755 | 16 | 0 | 0 | 39 | 39 | 39 | 空 |
| aahaDX 可用 | PK_aahaDX 可用 | 32 | 78675378 | 1 | 1 | 聚集索引 | IN_ROW_DATA | 3 | 0 | 87.7104377104377 | 2640 | 1.125 | 2970 | 80.2371756856931 | 327022 | 0 | 0 | 57 | 57 | 57 | 空 |
| aahaDX 可用 | PK_aahaDX 可用 | 32 | 78675378 | 1 | 1 | 聚集索引 | IN_ROW_DATA | 3 | 1 | 94.4444444444444 | 18 | 1 | 18 | 50.9389671361502 | 2970 | 0 | 0 | 23 | 23 | 23 | 空 |
| aahaDX 可用 | PK_aahaDX 可用 | 32 | 78675378 | 1 | 1 | 聚集索引 | IN_ROW_DATA | 3 | 2 | 0 | 1 | 1 | 1 | 5.53496417099086 | 18 | 0 | 0 | 23 | 23 | 23 | 空 |
+------------------+------------------ +-------------+------------+----------+------------ ------+--------------------+---------- +-------------+-------------+---------- ---------+----------------+------------------------ -----+------------+------------------------------- -+--------------+---------+------------ ----------------+--------------------------+------ -----------------+--------------+-- ----------------------+
+--------+
| 行 |
+--------+
| 327022 |
+--------+

为什么我的索引没有得到碎片整理?

sql-server sql-server-2005
  • 2 个回答
  • 2035 Views
Martin Hope
Scott Chamberlain
Asked: 2012-05-18 09:56:54 +0800 CST

对数据集执行“负传播”

  • 2

我有一种情况,代表未结余额和贷方的表都包含在一个表中。我需要做的是将所有未清信用额(最好是从最早开始的顺序,但不是必需的)应用到所有未清余额(从最早开始的顺序)。

例如(负余额代表贷方)

Account_ID  DateOfEntry  Balance  
----------  -----------  -------  
1           1/1/2012     10.00    
1           1/2/2012     -15.00
2           1/1/2012     -15.00
2           1/2/2012     10.00
3           1/1/2012     10.00
3           1/2/2012     1.00
3           1/3/2012     -5.00
4           1/1/2012     5.00
4           1/2/2012     5.00
4           1/3/2012     -7.00
5           1/1/2012     10.00
5           1/2/2012     -5.00
5           1/3/2012     -5.00

会变成:

Account_ID  DateOfEntry  Balance  
----------  -----------  -------    
1           1/2/2012     -5.00
2           1/1/2012     -5.00
3           1/1/2012     5.00
3           1/2/2012     1.00
4           1/2/2012     2.00

这是发生的事情的细目

  • 帐户 1 和帐户 2 留下信用(表明付款顺序和信用相对于彼此无关紧要)
  • 帐户 3 留下了两个余额(表明信用首先应用于最旧的余额)
  • 帐户 4 在 2012 年 1 月 2 日还剩一笔余额(表明如果第一个余额不满足信用额度,信用额度将应用于下一个最旧的余额)
  • 账户 5 消失了,因为贷方与余额完全匹配。

这是我的真实表中相关列的架构

CREATE TABLE [dbo].[IDAT_AR_BALANCES](
    [cvtGUID] [uniqueidentifier] ROWGUIDCOL  NOT NULL,
    [CLIENT_ID] [varchar](11) NOT NULL,
    [AGING_DATE] [datetime] NOT NULL,
    [AMOUNT] [money] NOT NULL,
 CONSTRAINT [PK_IDAT_ARBALANCES] PRIMARY KEY CLUSTERED ([cvtGUID] ASC)
)

目前我用一个游标循环所有可用的学分来做到这一点。

--Remove AR that totals to 0.
DELETE FROM IDAT_AR_BALANCES 
WHERE client_id IN ( 
SELECT client_id 
FROM IDAT_AR_BALANCES 
GROUP BY client_id 
HAVING SUM(amount) = 0)

--Spred the credits on to existing balances.
select * into #balances from [IDAT_AR_BALANCES] where amount > 0
select * into #credits from [IDAT_AR_BALANCES] where amount < 0

declare credit_cursor cursor for select [CLIENT_ID], amount, cvtGUID from #credits 

open credit_cursor 

declare @client_id varchar(11) 
declare @credit money 
declare @balance money 
declare @cvtGuidBalance uniqueidentifier 
declare @cvtGuidCredit uniqueidentifier 

fetch next from credit_cursor into @client_id, @credit, @cvtGuidCredit 
while @@fetch_status = 0 
begin 
  --While balances exist for the current client_ID and there are still credits to be applied, loop.
  while(@credit < 0 and (select count(*) from #balances where @client_id = CLIENT_ID and amount <> 0) > 0) 
  begin 
    --Find the oldest oustanding balance.
    select top 1  @balance = amount, @cvtGuidBalance = cvtGuid 
    from #balances 
    where @client_id = CLIENT_ID and amount <> 0 
    order by AGING_DATE 

    -- merge the balance and the credit
    set @credit = @balance + @credit 

    --If the credit is now postive save the leftover in the currently selected balance and set the credit to 0
    if(@credit > 0) 
    begin 
      update #balances set amount = @credit where cvtGuid = @cvtGuidBalance 
      set @credit = 0 
    end
    else -- Credit is larger than the balance, 0 out the balance and continue processesing
      update #balances set amount = 0 where cvtGuid = @cvtGuidBalance 

  end  -- end of while loop

  --There are no more balances to apply the credit to, save it back to the list.
  update #credits set amount = @credit where cvtGuid = @cvtGuidCredit 

  --Get the next credit.
  fetch next from credit_cursor into @client_id, @credit, @cvtGuidCredit 
end 
close credit_cursor 
deallocate credit_cursor

--Delete any balances and credits that where 0'ed out durning the spred negitive.
delete #balances where AMOUNT = 0
delete #credits where AMOUNT = 0

truncate table [IDAT_AR_BALANCES]
insert [IDAT_AR_BALANCES] select * from #balances
insert [IDAT_AR_BALANCES] select * from #credits
drop table #balances
drop table #credits

我确信有更好的方法可以做到这一点,所以我可以在没有光标的情况下做到这一点并从中获得更好的性能,但我很难弄清楚如何在不使用光标。

sql-server sql-server-2005
  • 2 个回答
  • 138 Views
Martin Hope
Scott Chamberlain
Asked: 2012-05-08 15:23:49 +0800 CST

最小化子表中不同列的父行数

  • 2

我有以下格式的三个表

A        B       C
-----    -----   -----
aKey     bKey    fk_c_b
         fk_b_a  c_enum
                 c_value

aKey并且bKey每个表都是主键,C没有主键。fk_b_a并且C.fk_c_b是指向父表的外键。c_enum是 87 个不同值的枚举。C.c_value是浮点数,可以是任何值

表之间的关系是:

  • ( A.aKey) 0..1 --- * ( B.fk_b_a)
  • ( B.bKey) 0..1 --- * ( C.fk_c_b)

有:

  • A 中 57,668 行
  • B 中的 650,768 行
  • C 中的 34,734 行

我需要显示所有c_enum值及其父母的不同列表,但是如果两行C共享相同的fk_c_b值c_value但不同的c_enum值,我可以不使用不同列表中的这两行。

select aKey, bKey, c_enum, c_value, newid() as id 
into #myResultSet
from A
inner join B on fk_b_a = aKey
inner join C as temp1 on fk_c_b = bKey
where c_value not in (select c_value from C as temp2 
                         where temp1.c_enum <> temp2.c_enum 
                            and temp1.fk_c_b = temp2.fk_c_b 
                            and temp1.c_value = temp2.c_value)

--This is the step that I do not know how to optimize
delete #myResultSet where id <> (select top 1 id from #myResultSet as t1 where #myResultSet.c_enum = t1.c_enum)

同样在该过程中,我需要最小化 aKey 和 bKey 的不同计数。所以如果我做了

select count(distinct aKey), count(distinct bKey), count(*) from #myResultSet

结果将具有可能的最小值。最佳结果是1, 1, 87,最坏情况是87, 87, 87。我当前的方法不会尝试获得最小值(我的结果还14, 17, 87不错,但我认为这只是这个数据集的运气,在不同的数据集上运行可能会返回更糟糕的结果)而且我在弄清楚时遇到了很多麻烦如何以正确的方式做到这一点。

解决这个问题的正确方法是什么?我目前的方法并不是最优的,我一直很难弄清楚我需要做什么来构建和#myResultSet的最小值。count(distinct aKey)count(distinct bKey)

sql-server-2005
  • 1 个回答
  • 209 Views
Martin Hope
Scott Chamberlain
Asked: 2012-05-05 05:37:31 +0800 CST

将文本列中的 RTF 批量转换为纯文本

  • 8

我有一个旧系统,表中有大约 1000 万行。在该表中有一个 type 列text,其中大部分是标准文本,但大约 50 万行中有 RTF 标记。我需要将 RTF 格式的文本转换为纯文本。

我当前的方法是我有一个 C# 程序,它使用 a 将查询加载到 DataTable 中,SqlDataAdapter并使用 winformsRichTextBox控件进行转换。

void bw_DoWork(object sender, DoWorkEventArgs e)
{
    count = 0;

    rtbRTFToPlain = new RichTextBox();

    using (SqlDataAdapter ada = new SqlDataAdapter("select note_guid, notes from client_notes", Globals.SQLConnectionString))
    using(SqlCommandBuilder cmb = new SqlCommandBuilder(ada))
    {
        DataTable dt = new DataTable();
        ada.UpdateCommand = cmb.GetUpdateCommand();

        ada.Fill(dt);

        int reportEvery = dt.Rows.Count / 100;
        if (reportEvery == 0)
            reportEvery = 1;
        foreach (DataRow row in dt.Rows)
        {
            if (count % reportEvery == 0)
                bw.ReportProgress(count / reportEvery);

            try
            {
                if (((string)row["notes"]).TrimStart().StartsWith("{") == true)
                {
                    rtbRTFToPlain.Rtf = (string)row["notes"];
                    row["notes"] = rtbRTFToPlain.Text;
                }
            }
            catch
            {
            }

            count++;

        }
        bw.ReportProgress(100);

        this.Invoke(new Action(() => 
            {
                this.ControlBox = false;
                this.Text = "Updating database please wait";
            }));
        ada.Update(dt);
    }
}

这对于小表来说非常有用,但是这是我第一次不得不在具有如此大数据集的表上运行它(一些 rtf 文件的大小可以是几兆字节,并带有嵌入的图片),而且我得到了 OutOfMemory我的 C# 程序出错。

我知道我可以将我的查询分成更小的批次,但我想看看是否有更好的方法可以去除 RTF 格式。

我应该只做与当前解决方案相同的事情,但一次只查询较小的数据块,还是有更好的方法来做到这一点?

sql-server sql-server-2005
  • 4 个回答
  • 26637 Views
Martin Hope
Scott Chamberlain
Asked: 2012-05-03 07:00:47 +0800 CST

是否可以执行 ALL SERVER DML Trigger?

  • 3

当客户从另一家公司切换到我们时,我的部门致力于转换客户的数据库。我们有一个 RDP 会话,他们可以连接并查看我们的软件及其数据。一旦他们批准转换,我们就会从我们的服务器复制数据并在现场为他们进行设置。

AFTER在转换批准阶段,如果我们可以在连接到服务器的所有数据库上运行一些和触发器,这将使我们的事情变得简单得多INSTEAD OF(我们的部门与开发软件的部门不同,他们不会制作版本对于为我们内置的东西的测试站点)。

我看到两个选项:

  1. 创建一个 DML 触发器,该触发器在连接到服务器的所有数据库上执行操作,但是当数据库移动到实时服务器时,该操作不再发生,因为它是在服务器而不是数据库上运行的。
  2. 有一个 DML 触发器,如果​​它检测到它不再连接到测试服务器并且处于实时环境中,它会自行删除。

从我阅读的内容来看,我认为第一个选项是不可能的,但我想检查一下。我想我足够了解第二个选项,但是任何如何实现它的例子都会非常有帮助。

sql-server sql-server-2005
  • 2 个回答
  • 1588 Views

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    连接到 PostgreSQL 服务器:致命:主机没有 pg_hba.conf 条目

    • 12 个回答
  • Marko Smith

    如何让sqlplus的输出出现在一行中?

    • 3 个回答
  • Marko Smith

    选择具有最大日期或最晚日期的日期

    • 3 个回答
  • Marko Smith

    如何列出 PostgreSQL 中的所有模式?

    • 4 个回答
  • Marko Smith

    列出指定表的所有列

    • 5 个回答
  • Marko Smith

    如何在不修改我自己的 tnsnames.ora 的情况下使用 sqlplus 连接到位于另一台主机上的 Oracle 数据库

    • 4 个回答
  • Marko Smith

    你如何mysqldump特定的表?

    • 4 个回答
  • Marko Smith

    使用 psql 列出数据库权限

    • 10 个回答
  • Marko Smith

    如何从 PostgreSQL 中的选择查询中将值插入表中?

    • 4 个回答
  • Marko Smith

    如何使用 psql 列出所有数据库和表?

    • 7 个回答
  • Martin Hope
    Jin 连接到 PostgreSQL 服务器:致命:主机没有 pg_hba.conf 条目 2014-12-02 02:54:58 +0800 CST
  • Martin Hope
    Stéphane 如何列出 PostgreSQL 中的所有模式? 2013-04-16 11:19:16 +0800 CST
  • Martin Hope
    Mike Walsh 为什么事务日志不断增长或空间不足? 2012-12-05 18:11:22 +0800 CST
  • Martin Hope
    Stephane Rolland 列出指定表的所有列 2012-08-14 04:44:44 +0800 CST
  • Martin Hope
    haxney MySQL 能否合理地对数十亿行执行查询? 2012-07-03 11:36:13 +0800 CST
  • Martin Hope
    qazwsx 如何监控大型 .sql 文件的导入进度? 2012-05-03 08:54:41 +0800 CST
  • Martin Hope
    markdorison 你如何mysqldump特定的表? 2011-12-17 12:39:37 +0800 CST
  • Martin Hope
    Jonas 如何使用 psql 对 SQL 查询进行计时? 2011-06-04 02:22:54 +0800 CST
  • Martin Hope
    Jonas 如何从 PostgreSQL 中的选择查询中将值插入表中? 2011-05-28 00:33:05 +0800 CST
  • Martin Hope
    Jonas 如何使用 psql 列出所有数据库和表? 2011-02-18 00:45:49 +0800 CST

热门标签

sql-server mysql postgresql sql-server-2014 sql-server-2016 oracle sql-server-2008 database-design query-performance sql-server-2017

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve