Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/82.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_Insert_Sql Server 2016 - Fatal编程技术网

SQL Server不存在时如何插入?

SQL Server不存在时如何插入?,sql,sql-server,insert,sql-server-2016,Sql,Sql Server,Insert,Sql Server 2016,我有两个表,一个叫做发票,另一个叫做记录 CREATE TABLE Invoices ( InvoiceNum INT NOT NULL, Amount DECIMAL, RecordPK UNIQUEIDENTIFIER NOT NULL ) CREATE TABLE Records( RecordPK UNIQUEIDENTIFIER NOT NULL PRIMARY KEY, StartNum INT NOT NULL, NextNum I

我有两个表,一个叫做发票,另一个叫做记录

CREATE TABLE Invoices
(
    InvoiceNum INT NOT NULL,
    Amount DECIMAL,
    RecordPK UNIQUEIDENTIFIER NOT NULL
)

CREATE TABLE Records(
    RecordPK UNIQUEIDENTIFIER NOT NULL PRIMARY KEY,
    StartNum INT NOT NULL,
    NextNum INT NOT NULL,
    MaxNum INT NOT NULL,
    InvPrefix VARCHAR(2) NOT NULL
)
记录表将记录发票开始编号、我们创建了多少发票以及我们可以创建多少发票

例如,假设两个表中有多条记录

发票表:

InvoiceNum    Amount    RecordPk
1             19.00     EDFA0541-5583-4CDD-BDFF-21D6F6504522
2             50.00     EDFA0541-5583-4CDD-BDFF-21D6F6504522
3             3.00      EDFA0541-5583-4CDD-BDFF-21D6F6504522
10            1.00      D64EFF0E-65D5-467E-8C82-BFBB6A24AAC9
11            99.00     D64EFF0E-65D5-467E-8C82-BFBB6A24AAC9
12            13.00     D64EFF0E-65D5-467E-8C82-BFBB6A24AAC9
记录表:

RecordPk                                StartNum    NextNum    MaxNum    Prefix
EDFA0541-5583-4CDD-BDFF-21D6F6504522    1           4          10        AA
D64EFF0E-65D5-467E-8C82-BFBB6A24AAC9    10          13         14        AA
我的问题是,当我搜索前缀为AA的发票表时,如何得到如下结果,InvoiceNum应达到最大值,不存在行的金额和RecordPK应保留为空,备注栏应填充为空

InvoiceNum    Amount    RecordPk                                Remark
1             19.00     EDFA0541-5583-4CDD-BDFF-21D6F6504522
2             50.00     EDFA0541-5583-4CDD-BDFF-21D6F6504522
3             3.00      EDFA0541-5583-4CDD-BDFF-21D6F6504522
4                                                               Blank
5                                                               Blank
6                                                               Blank
7                                                               Blank
8                                                               Blank
9                                                               Blank
10            1.00      D64EFF0E-65D5-467E-8C82-BFBB6A24AAC9
11            99.00     D64EFF0E-65D5-467E-8C82-BFBB6A24AAC9
12            13.00     D64EFF0E-65D5-467E-8C82-BFBB6A24AAC9
13                                                              Blank
14                                                              Blank

您需要生成一个包含数字的表,以覆盖记录表中每一行所需的数字范围,从StartNum到MaxNum。例如,您可以通过从一些具有足够行的现有表中选择并使用窗口函数来实现。然后过滤此序列,使其仅包含所需的数字。左键连接发票表以显示相应发票的数据,并使用函数检查是否存在具有此编号的发票

declare @Invoices table(InvoiceNum INT NOT NULL, Amount DECIMAL, RecordPK UNIQUEIDENTIFIER NOT NULL)
declare @Records table(RecordPK UNIQUEIDENTIFIER NOT NULL PRIMARY KEY, StartNum INT NOT NULL, NextNum INT NOT NULL, MaxNum INT NOT NULL, InvPrefix VARCHAR(2) NOT NULL)

insert into @Invoices(InvoiceNum, Amount, RecordPk) values
(1 ,            19.00,    'EDFA0541-5583-4CDD-BDFF-21D6F6504522'),
(2 ,            50.00,    'EDFA0541-5583-4CDD-BDFF-21D6F6504522'),
(3 ,            3.00 ,    'EDFA0541-5583-4CDD-BDFF-21D6F6504522'),
(10,            1.00 ,    'D64EFF0E-65D5-467E-8C82-BFBB6A24AAC9'),
(11,            99.00,    'D64EFF0E-65D5-467E-8C82-BFBB6A24AAC9'),
(12,            13.00,    'D64EFF0E-65D5-467E-8C82-BFBB6A24AAC9')

insert into @Records(RecordPk, StartNum, NextNum, MaxNum, InvPrefix) values
('EDFA0541-5583-4CDD-BDFF-21D6F6504522',    1 ,          4 ,         10,        'AA'),
('D64EFF0E-65D5-467E-8C82-BFBB6A24AAC9',    10,          13,         14,        'AA')

;with numbers as (select ROW_NUMBER() over(order by object_id) as No from sys.objects)
select
    n.No as InvoiceNum
    , inv.Amount
    , inv.RecordPK
    , IIF(inv.InvoiceNum is null, 'Blank', null) as Remark
from numbers n
left join @Invoices inv on n.No = inv.InvoiceNum
where exists(select * from @Records r where r.StartNum <= n.No and n.No <= r.MaxNum)
你需要一个左连接

SELECT I.*,
       CASE WHEN I.InvoiceNum IS NULL THEN 'Blank' END Remark
FROM (VALUES (1), (2), (3), (4), (5), (6), (7), (8), (9), (10), (11), (12), (13), (14)) RC (InvoiceNum)
LEFT JOIN Invoices I
     ON RC.InvoiceNum = I.InvoiceNum;
值1是StartNum,14是MAX MaxNum。 我使用了值,因为数字是已知的,您可以使用递归CTE生成缺少的InvoiceNum,然后将CTE与表左键连接


@安德烈·尼科洛夫(Andrey Nikolov)对此进行了报道,但我在过去15分钟里一直在做这件事,所以我想无论如何我都会发布它

<>基本上应该使用中间表来计数你没有的值,然后在我的版本中,我使用了一个联合查询来生成空白值。为了简洁起见,我没有包括唯一标识符,但应用程序是相同的

if OBJECT_ID('tempdb..#invoice') is not null drop table #invoice;
if OBJECT_ID('tempdb..#rowcount') is not null drop table #rowcount;

create table #invoice
    (
        invoicenum int,
        amount decimal
    );


insert into #invoice (invoicenum, amount)
values
(1, 19.00),
(2, 50.00),
(3, 3.00),
(10, 1.00),
(11, 99.00),
(12, 13.00);


create table #rowcount

    (
        rownumber int 
    );

declare @max int = 1;

select @max=count(*) from #invoice;

declare @runs int = 1;

while @runs<=@max
begin
insert into #rowcount (rownumber)
values (@runs);
select @runs=@runs+1;
end


select invoicenum, cast(amount as nvarchar(25)) as amount from #invoice
union
select rownumber, 'BLANK' from #rowcount r left join #invoice i on 
r.rownumber=i.invoicenum where i.invoicenum is null
order by invoicenum;

drop table #invoice, #rowcount;
我会这样做:

    IF OBJECT_ID('tempdb..#Invoices') IS NOT NULL DROP TABLE #Invoices

    CREATE TABLE #Invoices
    (
        InvoiceNum INT NOT NULL,
        Amount DECIMAL,
        RecordPK UNIQUEIDENTIFIER NOT NULL
    )

    IF OBJECT_ID('tempdb..#Records') IS NOT NULL DROP TABLE #Records

    CREATE TABLE #Records(
        RecordPK UNIQUEIDENTIFIER NOT NULL PRIMARY KEY,
        StartNum INT NOT NULL,
        NextNum INT NOT NULL,
        MaxNum INT NOT NULL,
        InvPrefix VARCHAR(2) NOT NULL
    )

    INSERT INTO #Invoices
    SELECT 1, 19.00, 'EDFA0541-5583-4CDD-BDFF-21D6F6504522'
    UNION SELECT 2 , 50.00, 'EDFA0541-5583-4CDD-BDFF-21D6F6504522'
    UNION SELECT 3 , 3.00 , 'EDFA0541-5583-4CDD-BDFF-21D6F6504522'
    UNION SELECT 10 , 1.00 , 'D64EFF0E-65D5-467E-8C82-BFBB6A24AAC9'
    UNION SELECT 11 , 99.00, 'D64EFF0E-65D5-467E-8C82-BFBB6A24AAC9'
    UNION SELECT 12 , 13.00, 'D64EFF0E-65D5-467E-8C82-BFBB6A24AAC9'

    INSERT INTO #Records
    SELECT 'EDFA0541-5583-4CDD-BDFF-21D6F6504522', 1, 4, 10, 'AA'
    UNION SELECT 'D64EFF0E-65D5-467E-8C82-BFBB6A24AAC9', 10, 13, 14, 'AA'

    DECLARE @MAX_NUM INT = (SELECT MAX(MaxNum) FROM #Records)
    DECLARE @TEMP_INV TABLE (InvoiceNum INT)
    INSERT INTO @TEMP_INV
    SELECT Num
    FROM
    (
        SELECT ROW_NUMBER() OVER(ORDER BY object_id) AS Num FROM sys.objects
    ) A
    WHERE Num <= @MAX_NUM

    IF OBJECT_ID('tempdb..#TEMP') IS NOT NULL DROP TABLE #TEMP

    SELECT I.InvoiceNum, I.Amount, I.RecordPK
    INTO #TEMP
    FROM #Invoices I
    INNER JOIN #Records R
        ON I.RecordPK = R.RecordPK
    WHERE R.InvPrefix = 'AA'

    SELECT A.InvoiceNum, B.Amount, B.RecordPK, CASE WHEN B.InvoiceNum IS NULL THEN 'BLANK' END AS Remark
    FROM @TEMP_INV A
    LEFT JOIN #TEMP B
        ON A.InvoiceNum = B.InvoiceNum

谢谢Sami,实际上,发票表中的行可以是数千行。