簡體   English   中英

如何創建存儲過程以遞歸計數許可證?

[英]How to create a Stored Procedure to count licences recursively?

我對SQL的經驗很少,但現在遇到了麻煩。

所以我想要的是以下內容。 我們制作安裝包,以安裝預先配置的應用程序。 這些軟件包將使用應用程序的名稱創建一個注冊表項。 我閱讀了此注冊表項,然后將其插入到SQL數據庫中。

我的許可證表包含以下列。
- 包裹名字
- 顯示名稱
-買了
- 自由
-替代許可證
-自定義

問題在於此SubstitueLicense。 所以我想做一個存儲過程,該過程應按以下方式工作。 如果記錄的替代許可證的值為Free,並且Free為0,則應減少替代許可證的Free值。 我制作了一個存儲過程,如果substitulicense沒有價值,它可以正常工作,但是我不知道如何做其余的工作。

USE [HWSW_Inventory]
GO
/****** Object:  StoredProcedure [dbo].[InsertWrapAppAndDecrementLicence]    Script Date: 12/30/2011 22:45:37 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO

ALTER PROCEDURE [dbo].[InsertWrapAppAndDecrementLicence]
-- Add the parameters for the stored procedure here
@String    varchar( 8000 ),
@HostName  varchar( 50 )
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;

-- Insert statements for procedure here
declare @LineIdx        int
declare @PackageIdx     int
declare @Line           varchar( 8000 )
declare @InsertValues   varchar( 4000 )
declare @PackageName    varchar( 200 )
declare @Command        varchar( 8000 )

select @LineIdx = 1

if ( ( len( @String ) < 1 ) or ( @String is null ) ) return
while ( @LineIdx != 0 )
begin
    --set LineIdx to the first occurence of a line separator
    set @LineIdx = charindex( ';', @String )
    if ( @LineIdx != 0 ) set @Line = left( @String, @LineIdx - 1 )
    else set @Line = @String

    --replace value delimeters and concatenate the hostname so we have a string what we can insert into the database
    set @InsertValues = '''' + REPLACE( @Line, '|', ''', ''') + ''', ''' + @HostName + ''''

    --get the first occurence of a ',' from the string what we want to insert, because it is the PackageName
    set @PackageIdx = CHARINDEX( '|', @String )
    if ( @PackageIdx != 0 ) set @PackageName = left( @String, @PackageIdx - 1 )
    else set @PackageName = @String

    set @Command = 'insert into dbo.WrapperApplications values ( ' + @InsertValues + ' )'
    exec ( @Command )

    update Licences set Free = Free - 1 where ( Licences.PackageName = @PackageName )

    set @String = right( @String, len( @String ) - @LineIdx )
    if ( len( @String ) = 0 ) break
end--while
END--main

有人可以幫我解決這個問題嗎?

謝謝!

更新:

對不起,我忘了告訴我們,替代許可是nvarchar類型。 它包含另一個軟件包名稱。 我需要這個,因為例如我們有100個Office 2007許可證和50個Office 2010許可證。 但是Office 2010許可證也可以用於Office 2007,因此我們可以使用150個Office2007。當然,該表中還存在packaga替代授權值,該值是我要減少的值。 希望你現在明白我的意思

我認為您遇到的部分困難(尤其是遞歸計數-如果您要逐行嘗試在SQL中執行某些操作,則這是一個很好的指標,您可能希望了解一下自己的方式建物)與數據庫的結構有關。

您試圖做的是建立一個經典的資源分配跟蹤器-如果您有10個Office 2007許可證,則要跟蹤注冊了哪些計算機才能使用這些許可證。 具有比您的許可證更多的活動軟件注冊是麻煩的根源。

請考慮以下有關該問題的事實:您具有要跟蹤的X許可證和Y安裝注冊。

許可證是一種具有某些屬性的事物:

  • 它用於特定的軟件版本,例如“ Office 2007”或“ Windows 7”或“ Office 2010”或...等。
  • 它允許您運行特定數量的指定軟件實例。
  • 在您的情況下,某些許可證可以代替其他許可證-例如,Office 2010許可證可用於Office 2007安裝。

同樣, 注冊是一種具有某些屬性的事物:

  • 它顯示了執行安裝時軟件許可證的用法
  • 它顯示安裝在特定計算機上。

考慮到這些事實,我構造了一組表:

Licenses:
License_ID          integer identity(1,1)
Package_Name        varchar( 200 )
Display_Name        varchar( 400 )
Bought              integer

上表僅包含有關每種許可證類型的信息。

License_Substitutes:
Substitute_ID       integer identity(1,1)
License_ID          integer
Allowed_Sub_License integer

該表包含有關不同許可證之間關系的信息; 在這種情況下,此表中的每一行都顯示“允許此License_ID代替指定的Allowed_Sub_License”。

Registrations:
Registration_ID     integer identity(1,1)
Installed_License   integer
Substitute_License  integer
Description         varchar(80)

如果您的注冊表項中還有其他我不知道的信息(例如,誰在注冊,在哪里或在什么計算機等),則此表中的列將是存儲該數據的最佳方法。

讓我們以您提到的兩個許可證(Office 2007和Office 2010)並將它們放入“許可證”表中為例:

License_ID  Package_Name    Display_Name            Bought
1           Off2007         Microsoft Office 2007   1
2           Off2010         Microsoft Office 2010   1

我們只買了一份,沒什么特別的。 根據您的規則,我們還知道2010許可證可以代替2007許可證,因此License_Substitutes看起來像:

Substitute_ID   License_ID  Allowed_Sub_License
1               2           1

輸入許可證並確定替換關系后,即可使用這些許可證注冊軟件。 如果要在我的計算機上注冊2007年的副本,則注冊將類似於:

Registration_ID     Installed_License   Substitute_License  Description
1                   1                   NULL                Mikurski's computer

Substitute_License保留為NULL,因為該注冊不需要替代。

但是,假設您現在在計算機上安裝了2007。 注冊看起來像:

Registration_ID     Installed_License   Substitute_License  Description
1                   1                   NULL                Mikurski's computer
1                   1                   2                   kampi's computer

此處的Substitute_License記錄為2(對於Office 2010)。 License_Substitutes.Substitute_ID只是一個標識值,用於使行保持不同。

您會注意到“免費”不再在此處作為列。 這是因為可以在查詢中計算許可證的可用點數:

select count(*) from Registrations
where   (installed_license = @Your_License_ID and substitute_license is NULL)
        or substitute_license = @Your_License_ID

這樣對數據庫進行規范化(有關規范化的更多信息,我發現是一個不錯的介紹)有助於最大程度地減少維護數據完整性所需的維護工作量,並且如果您的數據庫更易於擴展,未來需要改變。

假設SubstitueLicense為整數類型:

update
  Licences set Free = Free - 1
where
  (
    Licences.PackageName = @PackageName and
    Licenses.SubstitueLicese > 0 and
    Licenses.Free = 0
  )

那應該滿足您的要求: 如果記錄的替代許可證的值為Free,而Free為0,則應減小替代許可證的Free值。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM