我对SQL的经验很少,现在我被卡住了。
所以我想要的是以下内容。我们制作安装包,以安装预先配置的应用程序。这些包将使用应用程序的名称创建一个注册表项。我读了这个注册表项,然后我将它插入到SQL数据库中。
我的许可证表格包含以下列
- PackageName
- DisplayName
- 买了
- 免费
- 替代许可证
- 自定义
问题在于SubstitueLicense。所以我想制作一个应该以下列方式工作的存储过程。如果记录的替代许可具有值且Free为0,则应减少替代许可证的免费值。我制作了一个存储过程,如果替代品没有价值,它可以正常工作,但我不知道如何做其余的事。
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个Office 2007.当然,在这个表中也存在什么替代品值的packaga,这个值是我想要减少的。希望你现在明白我的意思
答案 0 :(得分:1)
我认为你遇到的部分困难(特别是对于递归计数 - 如果你试图逐行地在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)
如果您在注册表项中有其他我不知道的信息(例如注册的对象,地点或计算机等),此表中的列将是存储该数据的最佳方式。< / p>
我们将您提到的两个许可证(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只是一个标识值,用于保持行不同。
你会注意到'Free'不再是一个专栏了。这是因为可以在查询中计算许可证的空闲点数:
select count(*) from Registrations
where (installed_license = @Your_License_ID and substitute_license is NULL)
or substitute_license = @Your_License_ID
像这样规范化数据库(有关规范化的更多信息,我发现this是一个很好的介绍)有助于最大限度地减少维护数据完整性所需的维护工作量,并且意味着数据库如果您的需求在未来发生变化,将会更容易扩展。
答案 1 :(得分:0)
假设SubstitueLicense的类型为整数:
update
Licences set Free = Free - 1
where
(
Licences.PackageName = @PackageName and
Licenses.SubstitueLicese > 0 and
Licenses.Free = 0
)
这应符合您的要求:如果记录的替代许可具有值且Free为0,则替代许可证的免费值应减少