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-9003

Taryn's questions

Martin Hope
Taryn
Asked: 2019-12-20 10:23:15 +0800 CST

为什么具有聚集列存储索引的表会有许多打开的行组?

  • 22

昨天我在查询时遇到了一些性能问题,经过进一步调查,我注意到我认为我正试图深入了解的聚集列存储索引的奇怪行为。

该表是

CREATE TABLE [dbo].[NetworkVisits](
    [SiteId] [int] NOT NULL,
    [AccountId] [int] NOT NULL,
    [CreationDate] [date] NOT NULL,
    [UserHistoryId] [int] NOT NULL
)

与索引:

CREATE CLUSTERED COLUMNSTORE INDEX [CCI_NetworkVisits] 
   ON [dbo].[NetworkVisits] WITH (DROP_EXISTING = OFF, COMPRESSION_DELAY = 0) ON [PRIMARY]

该表目前有 13 亿行,我们不断地向其中插入新行。当我说不断时,我的意思是一直。这是一次向表中插入一行的稳定流。

Insert Into NetworkVisits (SiteId, AccountId, CreationDate, UserHistoryId)
Values (@SiteId, @AccountId, @CreationDate, @UserHistoryId)

执行计划在这里

我还有一个计划作业,每 4 小时运行一次,以从表中删除重复的行。查询是:

With NetworkVisitsRows
  As (Select SiteId, UserHistoryId, Row_Number() Over (Partition By SiteId, UserHistoryId
                                    Order By CreationDate Asc) RowNum
        From NetworkVisits
       Where CreationDate > GETUTCDATE() - 30)
DELETE
FROM NetworkVisitsRows
WHERE RowNum > 1
Option (MaxDop 48)

执行计划已粘贴在这里。

在深入研究这个问题时,我注意到该NetworkVisits表中有大约 2000 个行组,其中大约 800 个处于打开状态,并且没有接近允许的最大值 (1048576)。这是我所看到的一个小样本:

在此处输入图像描述

我对索引进行了重组,压缩了除 1 个行组之外的所有行组,但今天早上我再次检查,我们再次有多个打开的行组 - 昨天在重组后创建的行组,然后大约在删除时创建了 3 个其他行组工作运行:

TableName       IndexName           type_desc               state_desc  total_rows  deleted_rows    created_time
NetworkVisits   CCI_NetworkVisits   CLUSTERED COLUMNSTORE   OPEN        36754       0               2019-12-18 18:30:54.217
NetworkVisits   CCI_NetworkVisits   CLUSTERED COLUMNSTORE   OPEN        172103      0               2019-12-18 20:02:06.547
NetworkVisits   CCI_NetworkVisits   CLUSTERED COLUMNSTORE   OPEN        132628      0               2019-12-19 04:03:10.713
NetworkVisits   CCI_NetworkVisits   CLUSTERED COLUMNSTORE   OPEN        397718      0               2019-12-19 08:02:13.063

我正在尝试确定可能导致创建新行组而不是使用现有行组的原因。

插入和删除之间是否可能存在内存压力或争用?这种行为是否记录在任何地方?

我们在此服务器上运行 SQL Server 2017 CU 16 企业版。

是INSERTMAXDOP 0,DELETE是 MAXDOP 48。唯一关闭的行组是最初的行组BULKLOAD,然后REORG_FORCED是我昨天做的行组,所以修剪的原因分别sys.dm_db_column_store_row_group_physical_stats是REORG和NO_TRIM。除此之外没有封闭的行组。没有针对此表运行的更新。我们在插入语句上平均每分钟执行约 520 次。表上没有分区。

我知道涓流插入。我们在其他地方做同样的事情,并且在多个开放行组中没有遇到同样的问题。我们怀疑它与删除有关。每个新创建的行组都在计划删除作业的时间附近。只有两个增量存储显示已删除的行。我们实际上并没有从这个表中删除很多数据,例如在昨天的一次执行中,它删除了 266 行。

sql-server sql-server-2017
  • 3 个回答
  • 1607 Views
Martin Hope
Taryn
Asked: 2018-03-15 09:12:43 +0800 CST

服务器重新启动后 SQL Server 分布式可用性组数据库不同步

  • 22

我们正准备在我们的 SQL Server 上执行大规模升级,并注意到分布式可用性组的一些异常行为,我试图在继续之前解决这些行为。

上个月,我将远程辅助服务器从 SQL Server 2016 升级到 SQL Server 2017。该服务器是多个分布式可用性组 (DAG)和单独的可用性组 (AG)的一部分。当我们升级这台服务器时,我们并没有意识到它会进入一个不可读的状态,所以在过去的一个月里,我们一直只依赖于主服务器。

作为即将进行的升级的一部分,我将CU 4补丁应用到服务器并重新启动它。当服务器重新上线时,刚刚修补的辅助服务器显示所有 DAG/AG 正在同步,没有任何问题。

然而,初选展示了一个非常不同的故事。据报道

  • 单独的 AG 正在同步,没有任何问题
  • 但 DAG 处于不同步/不健康状态

在最初惊慌失措之后,我尝试了以下操作以使 DAG 中的事物再次同步:

  • 从主节点开始,我停止并恢复了数据移动。这没有开始同步数据。
  • 在第二个(我刚刚修补的那个)上我运行了ALTER DATABASE [<database] SET HADR RESUME;- 它执行没有错误,但没有恢复任何同步

我最后一次尝试再次同步数据是登录到辅助服务器,然后手动重新启动 SQL Server 服务。手动重新启动服务似乎有点极端,因为我希望重新启动服务器就足够了。

有没有人遇到过重启后 DAG 没有开始同步到辅助服务器的问题?如果是这样,它是如何解决的?

我检查了 SQL Server 错误日志和辅助服务器上的事件查看器,我看不到任何异常。

sql-server availability-groups
  • 3 个回答
  • 7169 Views
Martin Hope
Taryn
Asked: 2013-12-04 06:11:52 +0800 CST

为什么 SQL Server 在使用 UNPIVOT 时要求数据类型长度相同?

  • 30

将UNPIVOT函数应用于未规范化的数据时,SQL Server 要求数据类型和长度相同。我明白为什么数据类型必须相同,但为什么 UNPIVOT 要求长度相同?

假设我有以下需要取消透视的示例数据:

CREATE TABLE People
(
    PersonId int, 
    Firstname varchar(50), 
    Lastname varchar(25)
)

INSERT INTO People VALUES (1, 'Jim', 'Smith');
INSERT INTO People VALUES (2, 'Jane', 'Jones');
INSERT INTO People VALUES (3, 'Bob', 'Unicorn');

如果我尝试 UNPIVOTFirstname和Lastname列类似于:

select PersonId, ColumnName, Value  
from People
unpivot
(
  Value 
  FOR ColumnName in (FirstName, LastName)
) unpiv;

SQL Server 生成错误:

消息 8167,第 16 层,状态 1,第 6 行

“姓氏”列的类型与 UNPIVOT 列表中指定的其他列的类型冲突。

为了解决错误,我们必须使用子查询首先将Lastname列强制转换为具有相同的长度Firstname:

select PersonId, ColumnName, Value  
from
(
  select personid, 
    firstname, 
    cast(lastname as varchar(50)) lastname
  from People
) d
unpivot
(
  Value FOR 
  ColumnName in (FirstName, LastName)
) unpiv;

请参阅带有演示的 SQL Fiddle

在 SQL Server 2005 中引入 UNPIVOT 之前,我将使用SELECTwithUNION ALL来取消透视firstname/lastname列,并且查询将运行而无需将列转换为相同的长度:

select personid, 'firstname' ColumnName, firstname value
from People
union all
select personid, 'LastName', LastName
from People;

请参阅SQL Fiddle with Demo。

我们还能够使用CROSS APPLY在数据类型上没有相同长度的情况下成功地取消透视数据:

select PersonId, columnname, value
from People
cross apply
(
    select 'firstname', firstname union all
    select 'lastname', lastname
) c (columnname, value);

请参阅SQL Fiddle with Demo。

我已通读 MSDN,但没有找到任何解释强制数据类型长度相同的原因。

使用 UNPIVOT 时要求相同长度背后的逻辑是什么?

sql-server unpivot
  • 2 个回答
  • 18731 Views
Martin Hope
Taryn
Asked: 2013-05-23 13:05:28 +0800 CST

如何让 row_number 具有 dense_rank 的行为

  • 4

我有一个存储过程将用于翻阅数据。该过程的要求之一是要有一个参数,用于对两列数据进行排序,在应用row_number().

一些示例数据:

CREATE TABLE grp 
(
  [grp_id] uniqueidentifier primary key, 
  [grp_nm] varchar(5) not null, 
  [grp_owner] varchar(200) not null
);

INSERT INTO grp ([grp_id], [grp_nm], [grp_owner])
VALUES
    ('7F5F0F16-4EBE-E211-9C26-78E7D18E1E84', 'test1', 'me'),
    ('1F52A713-EFAC-E211-9C26-78E7D18E1E84', 'test2', 'me'),
    ('D123B48A-63AB-E211-9C26-78E7D18E1E84', 'test3', 'me'),
    ('48361F86-2BC2-E211-9C26-78E7D18E1E84', 'test4', 'me'),
    ('27429A57-93C1-E211-9C26-78E7D18E1E84', 'test5', 'me'),
    ('D5DF9F8E-EDC2-E211-9C26-78E7D18E1E84', 'test6', 'me'),
    ('9A07EA21-1AAD-E211-9C26-78E7D18E1E84', 'test7', 'me');


CREATE TABLE mbr
(
  [grp_id] uniqueidentifier, 
  [mbr_id] int not null primary key, 
  [acct_id] varchar(7) not null, 
  [cst] varchar(4) null
);

INSERT INTO mbr ([grp_id], [mbr_id], [acct_id], [cst])
VALUES
    ('7F5F0F16-4EBE-E211-9C26-78E7D18E1E84', 10, '1', 'AA'),
    ('7F5F0F16-4EBE-E211-9C26-78E7D18E1E84', 11, '2', 'BB'),
    ('1F52A713-EFAC-E211-9C26-78E7D18E1E84', 12, '1234578', 'blah'),
    ('D123B48A-63AB-E211-9C26-78E7D18E1E84', 13, '78', 'test'),
    ('48361F86-2BC2-E211-9C26-78E7D18E1E84', 14, 'x', 'mbr1'),
    ('48361F86-2BC2-E211-9C26-78E7D18E1E84', 15, 'a', 'mbr2'),
    ('27429A57-93C1-E211-9C26-78E7D18E1E84', 16, 'b', 'mbr1'),
    ('27429A57-93C1-E211-9C26-78E7D18E1E84', 17, 'c', 'mbr2'),
    ('D5DF9F8E-EDC2-E211-9C26-78E7D18E1E84', 18, 'a', 'mbr1'),
    ('9A07EA21-1AAD-E211-9C26-78E7D18E1E84', 19, 'a', 'mbr1');

该程序和排序目前正在按书面进行。

但是我们应用row_number(). row_number()应该几乎模拟发生的排名,但dense_rank由于使用参数排序,它不能按预期工作。

例如,如果我运行以下查询:

declare @sort_desc bit = 0

select g.grp_id, g.grp_nm,
    m.mbr_id, m.acct_id, m.cst,
    row_number() over(order by case when @sort_desc = 0 then g.grp_nm end
                              , case when @sort_desc = 0 then m.acct_id end
                              , case when @sort_desc = 1 then g.grp_nm end desc
                              , case when @sort_desc = 1 then m.acct_id end desc) rn,
    dense_rank()  over(order by case when @sort_desc = 0 then g.grp_nm end
                              , case when @sort_desc = 0 then m.acct_id end
                              , case when @sort_desc = 1 then g.grp_nm end desc
                              , case when @sort_desc = 1 then m.acct_id end desc) dr
from grp g
inner join mbr m
  on g.grp_id = m.grp_id;

请参阅带演示的 SQL Fiddle(还提供了一个精简的存储过程)

我得到以下结果:

|                               GRP_ID | GRP_NM | MBR_ID | ACCT_ID |  CST | RN | DR |
-------------------------------------------------------------------------------------
| 7F5F0F16-4EBE-E211-9C26-78E7D18E1E84 |  test1 |     10 |       1 |   AA |  1 |  1 |
| 7F5F0F16-4EBE-E211-9C26-78E7D18E1E84 |  test1 |     11 |       2 |   BB |  2 |  2 |
| 1F52A713-EFAC-E211-9C26-78E7D18E1E84 |  test2 |     12 | 1234578 | blah |  3 |  3 |
| D123B48A-63AB-E211-9C26-78E7D18E1E84 |  test3 |     13 |      78 | test |  4 |  4 |
| 48361F86-2BC2-E211-9C26-78E7D18E1E84 |  test4 |     15 |       a | mbr2 |  5 |  5 |
| 48361F86-2BC2-E211-9C26-78E7D18E1E84 |  test4 |     14 |       x | mbr1 |  6 |  6 |
| 27429A57-93C1-E211-9C26-78E7D18E1E84 |  test5 |     16 |       b | mbr1 |  7 |  7 |
| 27429A57-93C1-E211-9C26-78E7D18E1E84 |  test5 |     17 |       c | mbr2 |  8 |  8 |
| D5DF9F8E-EDC2-E211-9C26-78E7D18E1E84 |  test6 |     18 |       a | mbr1 |  9 |  9 |
| 9A07EA21-1AAD-E211-9C26-78E7D18E1E84 |  test7 |     19 |       a | mbr1 | 10 | 10 |

但想要的结果是:

|                               GRP_ID | GRP_NM | MBR_ID | ACCT_ID |  CST | RN | expR|
-------------------------------------------------------------------------------------
| 7F5F0F16-4EBE-E211-9C26-78E7D18E1E84 |  test1 |     10 |       1 |   AA |  1 |  1  |
| 7F5F0F16-4EBE-E211-9C26-78E7D18E1E84 |  test1 |     11 |       2 |   BB |  2 |  1  |
| 1F52A713-EFAC-E211-9C26-78E7D18E1E84 |  test2 |     12 | 1234578 | blah |  3 |  2  |
| D123B48A-63AB-E211-9C26-78E7D18E1E84 |  test3 |     13 |      78 | test |  4 |  3  |
| 48361F86-2BC2-E211-9C26-78E7D18E1E84 |  test4 |     15 |       a | mbr2 |  5 |  4  |
| 48361F86-2BC2-E211-9C26-78E7D18E1E84 |  test4 |     14 |       x | mbr1 |  6 |  4  |
| 27429A57-93C1-E211-9C26-78E7D18E1E84 |  test5 |     16 |       b | mbr1 |  7 |  5  |
| 27429A57-93C1-E211-9C26-78E7D18E1E84 |  test5 |     17 |       c | mbr2 |  8 |  5  |
| D5DF9F8E-EDC2-E211-9C26-78E7D18E1E84 |  test6 |     18 |       a | mbr1 |  9 |  6  |
| 9A07EA21-1AAD-E211-9C26-78E7D18E1E84 |  test7 |     19 |       a | mbr1 | 10 |  7  |

正如您所看到的,expR列值正在递增,grp_id但行仍处于正确的排序顺序中。我不知道如何得到这个结果,任何建议都会很好。

sql-server window-functions
  • 1 个回答
  • 604 Views
Martin Hope
Taryn
Asked: 2012-08-17 08:25:08 +0800 CST

关键字“as”附近的 BCP 错误

  • 2

我是使用 BCP 的新手,但我正在尝试提取通过存储过程生成的数据。这是我最初的问题的延续,这是一个带有临时表的存储过程。这个过程有点长,但核心是一样的,生成临时表,运行动态 SQL 来填充表,然后返回数据。

我很快意识到 bcp 通过错误不喜欢临时表:

SQLState = S0002,NativeError = 208

错误 = [Microsoft][SQL Server Native Client 10.0][SQL Server]无效的对象名称'#SurveyData

因此,我更改了我的程序以删除 #temp 表并使用实际表。但现在我得到一个错误:

SQLState = 37000,NativeError = 156

错误 = [Microsoft][SQL Server Native Client 10.0][SQL Server]关键字“as”附近的语法不正确

我相信问题出在动态 SQL 上。声明中有一个as。

SET @sql = 'INSERT INTO cl.Results ' +
                            ' SELECT s.SurveyId
                                , s.InstanceId
                                , CASE WHEN columnName = ''' +  @ColumnName + ''' THEN REPLACE(columnName, ''Q_'', '''') ELSE '''' END 
                                , Cast(s.' + @ColumnName + ' as varchar(1000))
                            FROM cl.SurveyData t 
                            INNER JOIN dbo.' + @TableName + ' s' +
                            ' ON REPLACE(t.tableName, ''Library_'', '''') = s.SurveyID ' +
                            ' WHERE t.columnName = ''' + @ColumnName + ''''

        exec(@sql)

我在 BCP 中用来执行的代码是:

bcp "exec dbo.getresults" queryout "c:\temp\mytext.txt" -S <myserver> -T -c -t^|

我愿意接受有关如何提取这些数据的任何建议,即使我必须重写存储过程。

我不能使用 BCP 来执行带有动态 SQL 的存储过程吗?如果没有,我还应该如何考虑提取这些数据?SSIS 似乎也不喜欢临时表或动态 SQL。

编辑:使用print(@sql)

INSERT INTO cl.Results  
SELECT s.SurveyId
    , s.InstanceId
    , CASE WHEN columnName = 'Q_1' THEN REPLACE(columnName, 'Q_', '') ELSE '' END 
    , Cast(s.Q_1 as varchar(1000))
FROM cl.SurveyData t 
INNER JOIN dbo.Library_1 s 
    ON REPLACE(t.tableName, 'Library_', '') = s.SurveyID  WHERE t.columnName = 'Q_1'

INSERT INTO cl.Results  
SELECT s.SurveyId
    , s.InstanceId
    , CASE WHEN columnName = 'Q_2' THEN REPLACE(columnName, 'Q_', '') ELSE '' END 
    , Cast(s.Q_2 as varchar(1000))
FROM cl.SurveyData t 
INNER JOIN dbo.Library_2 s 
    ON REPLACE(t.tableName, 'Library_', '') = s.SurveyID  WHERE t.columnName = 'Q_2'

INSERT INTO cl.Results  
SELECT s.SurveyId
    , s.InstanceId
    , CASE WHEN columnName = 'Q_3' THEN REPLACE(columnName, 'Q_', '') ELSE '' END 
    , Cast(s.Q_3 as varchar(1000))
FROM cl.SurveyData t 
INNER JOIN dbo.Library_2 s 
    ON REPLACE(t.tableName, 'Library_', '') = s.SurveyID  
WHERE t.columnName = 'Q_3'

INSERT INTO cl.Results  
SELECT s.SurveyId
    , s.InstanceId
    , CASE WHEN columnName = 'Q_4' THEN REPLACE(columnName, 'Q_', '') ELSE '' END 
    , Cast(s.Q_4 as varchar(1000))
FROM cl.SurveyData t 
INNER JOIN dbo.Library_2 s 
    ON REPLACE(t.tableName, 'Library_', '') = s.SurveyID  
WHERE t.columnName = 'Q_4'

编辑:这是我在没有任何临时表的情况下运行的完整脚本:

truncate table cl.Results
truncate table cl.SurveyData

-- insert the survey table structures for use
insert into cl.SurveyData (tableName, columnName, columnId, rownum)
select tables1.name, cols1.name, column_id, ROW_NUMBER() over(order by tables1.name, column_id)
from sys.all_columns cols1
inner join 
(
    SELECT *
    FROM sys.all_objects
    WHERE type = 'U' 
    AND upper(name) like 'LIBRARY%' 
) Tables1
    ON cols1.object_id = tables1.object_id
WHERE cols1.name Like 'Q_%'
ORDER BY tables1.name, column_id;


declare @sql varchar(max) = '';
declare @RowCount int = 1;
declare @TotalRecords int = (SELECT COUNT(*) FROM cl.SurveyData);

Declare @TableName varchar(50) = '';
Declare @ColumnName varchar(50) = '';

WHILE @RowCount <= @TotalRecords
    BEGIN

        SELECT @TableName = tableName, @ColumnName = columnName
        FROM cl.SurveyData
        WHERE @RowCount = rownum

        SET @sql = 'INSERT INTO cl.Results ' +
                    ' SELECT s.SurveyId
                        , s.InstanceId
                        , CASE WHEN columnName = ''' +  @ColumnName + ''' THEN REPLACE(columnName, ''Q_'', '''') ELSE '''' END 
                        , Cast(s.' + @ColumnName + ' as varchar(1000))
                    FROM cl.SurveyData t 
                    INNER JOIN dbo.' + @TableName + ' s' +
                    ' ON REPLACE(t.tableName, ''Library_'', '''') = s.SurveyID ' +
                    ' WHERE t.columnName = ''' + @ColumnName + ''''

        exec(@sql)

        SET @RowCount = @RowCount + 1       
    END

    SELECT r.SurveyId, 
        r.InstanceId, 
        CASE 
            when chat.DataName = 'BRKR_ACCT_ID' and chat.DataValue is not null then chat.DataValue
            when email.PropName = 'ACCT_ID' and email.PropValue is not null then email.PropValue
        END Account_ID,
        CASE 
            when chat.DataName = 'BRKR_CUST_ID' and chat.DataValue is not null then chat.DataValue
            when email.PropName = 'CUST_ID' and email.PropValue is not null then email.PropValue
        END Cust_ID,
        case 
            when chat.LoginName is null 
            then email.LoginName 
            else chat.LoginName 
        end SchwabId,
        case 
            when chat.CustEmail is null 
            then email.ReplyTo 
            else chat.CustEmail 
        end CustomerEmail,
        sp.DateSent,
        CONVERT(varchar, DATEADD(ms, DATEDIFF(SECOND, sp.datesent, sp.datecompleted) * 1000, 0), 108) ResponseTime,
        r.QuestionNumber,
        r.Response
    FROM cl.Results r
    INNER JOIN dbo.SurveyParam sp
        ON r.InstanceId = sp.InstanceID
        AND r.SurveyId = sp.SurveyID
    -- chat surveys uses Param4
    LEFT JOIN 
    (
        SELECT si.SessionID, 
            si.CustEmail, 
            u.LoginName, 
            ltrim(rtrim(sie.DataValue)) DataValue, 
            ltrim(rtrim(sie.DataName)) DataName
        FROM dbo.SessionInfo si
        LEFT JOIN dbo.Users u
            ON si.LastAgent = u.id
        LEFT JOIN dbo.SessionInfoExternals sie
            ON si.SessionID = sie.SessionID
        WHERE sie.DataName IN ('BRKR_ACCT_ID', 'BRKR_CUST_ID')
    ) chat
        ON sp.Param4 = chat.SessionID
    -- email surveys uses Param3
    LEFT JOIN
    (
        SELECT mm.MsgID, 
            mr.ReplyTo, 
            u.LoginName, 
            ltrim(rtrim(mie.PropValue)) PropValue,
            ltrim(rtrim(mie.PropName)) PropName
        FROM dbo.MailReply mr
        INNER JOIN dbo.MailMessage mm
            ON mr.ReplyToID = mm.MsgID
        LEFT JOIN dbo.Users u
            on mr.AgentID = u.ID
        LEFT JOIN dbo.MsgInfoExternals mie
            ON mm.IncidentID = mie.Instance
        WHERE mie.PropName IN ('CUST_ID', 'ACCT_ID')
    ) email
        ON sp.Param3 = email.MsgID
    WHERE sp.DateCompleted is not null
sql-server sql-server-2008
  • 1 个回答
  • 2050 Views
Martin Hope
Taryn
Asked: 2012-07-18 14:08:02 +0800 CST

存储过程返回动态创建的表数据

  • 10

简短的背景故事,我们正在与拥有调查系统的外部供应商合作。当您创建新调查并且系统创建新表时,系统不一定设计得最好,即:

Tables
____
Library_1 -- table for Survey 1
SurveyId int
InstanceId int
Q_1 varchar(50)

Library_2 -- table for Survey 2
SurveyId int
InstanceId int
Q_2 int
Q_3 int
Q_4 varchar(255)

生成的表格SurveyId名称末尾带有 ( Library_),而生成的问题列QuestionId末尾带有 ( Q_)。 为了澄清,问题存储在一个单独的表中,因此虽然问题 ID 是连续的,但它们不会从每个调查的 1 开始。问题列将基于表中分配给它们的 id。

查询起来似乎很简单,除了我们需要从所有调查表中提取数据以发送到另一个系统,这就是问题所在。由于表是在前台添加新调查时自动创建的 -最终应用程序,其他系统无法处理这种类型的结构。他们需要数据保持一致才能使用。

因此,我的任务是编写一个存储过程,该过程将从所有调查表中提取数据并将其放置在以下格式中:

SurveyId    InstanceId    QNumber    Response
________    __________    _______    ________
1           1             1          great
1           2             1          the best
2           9             2          10
3           50            50         test

通过使所有表格的数据采用相同的格式,任何人都可以使用它,无论存在多少调查表格和问题。

我编写了一个似乎正在工作的存储过程,但我想知道我是否遗漏了什么,或者是否有更好的方法来处理这种情况。

我的代码:

declare @sql varchar(max) = ''
declare @RowCount int = 1
declare @TotalRecords int = (SELECT COUNT(*) FROM SurveyData)

Declare @TableName varchar(50) = ''
Declare @ColumnName varchar(50) = ''

WHILE @RowCount <= @TotalRecords
    BEGIN

        SELECT @TableName = tableName, @ColumnName = columnName
        FROM SurveyData
        WHERE @RowCount = rownum


        SET @sql = @sql + 
            ' SELECT s.SurveyId
                , s.InstanceId
                , CASE WHEN columnName = ''' +  @ColumnName + ''' THEN REPLACE(columnName, ''Q_'', '''') ELSE '''' END as QuestionNumber
                , Cast(s.' + @ColumnName + ' as varchar(1000)) as ''Response''
            FROM SurveyData t 
            INNER JOIN ' + @TableName + ' s' +
                ' ON REPLACE(t.tableName, ''Library_'', '''') = s.SurveyID ' +
            ' WHERE t.columnName = ''' + @ColumnName + ''''

        IF @RowCount != @TotalRecords
            BEGIN
                set @sql = @sql + ' UNION ALL'
            END

        SET @RowCount = @RowCount + 1       
    END


exec(@sql)

我用一些示例数据和代码 创建了一个SQL Fiddle 。

这种类型的查询应该以不同的方式编写吗?它有什么明显的问题吗?

不幸的是,这有很多未知数......我们将拥有多少张表格以及每次调查有多少问题。 我想说我们将进行 25-50 次调查,每个调查有 2-5 个问题。

sql-server sql-server-2008-r2
  • 1 个回答
  • 32501 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