[英]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安裝注冊。
許可證是一種具有某些屬性的事物:
同樣, 注冊是一種具有某些屬性的事物:
考慮到這些事實,我構造了一組表:
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.