USE ManageSoft
SET QUOTED_IDENTIFIER ON
IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[DatabaseConfigurationGetByProperty]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[DatabaseConfigurationGetByProperty]
GO
CREATE PROCEDURE [dbo].[DatabaseConfigurationGetByProperty]
	@Property		varchar(32)
AS
	SELECT	Property,
		Value,
		Created,
		LastUpdate
	FROM	[dbo].[DatabaseConfiguration]
	WHERE	Property = @Property
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[DatabaseConfigurationGetAll]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[DatabaseConfigurationGetAll]
GO
CREATE PROCEDURE [dbo].[DatabaseConfigurationGetAll]
AS
	SELECT	Property,
		Value,
		Created,
		LastUpdate
	FROM	[dbo].[DatabaseConfiguration]
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[DatabaseConfigurationAdd]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[DatabaseConfigurationAdd]
GO
CREATE PROCEDURE [dbo].[DatabaseConfigurationAdd]
	@Property		varchar(32),
	@Value			varchar(256),
	@Created		datetime,
	@LastUpdate		datetime
AS
	INSERT INTO  dbo.DatabaseConfiguration (
		Property,
		Value,
		Created,
		LastUpdate
	)
	VALUES (
		@Property,
		@Value,
		@Created,
		@LastUpdate
	)
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[DatabaseConfigurationSchema]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[DatabaseConfigurationSchema]
GO
CREATE PROCEDURE [dbo].[DatabaseConfigurationSchema]
AS
	SELECT
	'IF OBJECT_ID(''tempdb..#DatabaseConfiguration'') IS NULL' + CAST(0x0A AS CHAR(1)) +
	'	CREATE TABLE #DatabaseConfiguration (' + CAST(0x0A AS CHAR(1)) +
	'		Property		varchar(32) COLLATE database_default NOT NULL,' + CAST(0x0A AS CHAR(1)) +
	'		Value			varchar(256) COLLATE database_default NOT NULL,' + CAST(0x0A AS CHAR(1)) +
	'		Created			datetime NOT NULL DEFAULT getdate(),' + CAST(0x0A AS CHAR(1)) +
	'		LastUpdate		datetime NOT NULL DEFAULT getdate()' + CAST(0x0A AS CHAR(1)) +
	'	)' + CAST(0x0A AS CHAR(1)) +
	'ELSE' + CAST(0x0A AS CHAR(1)) +
	'	DELETE FROM #DatabaseConfiguration' + CAST(0x0A AS CHAR(1)) +
	'' AS SQL
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[DatabaseConfigurationTempAdd]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[DatabaseConfigurationTempAdd]
GO
CREATE PROCEDURE dbo.[DatabaseConfigurationTempAdd]
	@Property		varchar(32),
	@Value			varchar(256),
	@Created		datetime,
	@LastUpdate		datetime
AS
	INSERT INTO #DatabaseConfiguration (
		Property,
		Value,
		Created,
		LastUpdate
	)
	VALUES (
		@Property,
		@Value,
		@Created,
		@LastUpdate
	)
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[DatabaseConfigurationAddBatch]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[DatabaseConfigurationAddBatch]
GO
CREATE PROCEDURE dbo.[DatabaseConfigurationAddBatch]
AS
	DECLARE @count int
	INSERT dbo.DatabaseConfiguration (
		Property,
		Value,
		Created,
		LastUpdate
	)
		SELECT	Property,
			Value,
			Created,
			LastUpdate
		FROM #DatabaseConfiguration
	SET @count = @@ROWCOUNT
	DROP TABLE #DatabaseConfiguration	-- Drop temporary table
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[DatabaseConfigurationUpdateByProperty]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[DatabaseConfigurationUpdateByProperty]
GO
CREATE PROCEDURE [dbo].[DatabaseConfigurationUpdateByProperty]
	@Property		varchar(32),
	@Value			varchar(256),
	@Created		datetime,
	@LastUpdate		datetime
AS
	UPDATE	[dbo].[DatabaseConfiguration]
	SET	Value = @Value,
		Created = @Created,
		LastUpdate = @LastUpdate
	WHERE	Property = @Property
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[DatabaseConfigurationUpdateBatchByProperty]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[DatabaseConfigurationUpdateBatchByProperty]
GO
CREATE PROCEDURE dbo.[DatabaseConfigurationUpdateBatchByProperty]
AS
	DECLARE @count int

	CREATE INDEX [TempDatabaseConfigurationProperty]
		ON #DatabaseConfiguration (Property)

	UPDATE	[dbo].[DatabaseConfiguration]
	SET	Value = t.Value,
		Created = t.Created,
		LastUpdate = t.LastUpdate
	FROM	#DatabaseConfiguration AS t
	WHERE	DatabaseConfiguration.Property = t.Property
	SET @count = @@ROWCOUNT
	DROP TABLE #DatabaseConfiguration	-- Drop the temporary table
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[DatabaseConfigurationPutByProperty]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[DatabaseConfigurationPutByProperty]
GO
CREATE PROCEDURE [dbo].[DatabaseConfigurationPutByProperty]
	@Property		varchar(32),
	@Value			varchar(256),
	@Created		datetime,
	@LastUpdate		datetime
AS
	IF NOT EXISTS(
		SELECT	1
		FROM	dbo.DatabaseConfiguration
		WHERE	Property = @Property
	)
		EXEC DatabaseConfigurationAdd @Property,
			@Value,
			@Created,
			@LastUpdate
	ELSE
		EXEC DatabaseConfigurationUpdateByProperty @Property,
			@Value,
			@Created,
			@LastUpdate
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[DatabaseConfigurationPutBatchByProperty]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[DatabaseConfigurationPutBatchByProperty]
GO
CREATE PROCEDURE [dbo].[DatabaseConfigurationPutBatchByProperty]
AS
	DECLARE @count AS int
	SET @count = 0

	CREATE INDEX [TempDatabaseConfigurationProperty]
		ON #DatabaseConfiguration (Property)

	BEGIN TRANSACTION
	UPDATE [dbo].[DatabaseConfiguration]
		SET	Value = t.Value,
			Created = t.Created,
			LastUpdate = t.LastUpdate
		FROM	#DatabaseConfiguration AS t
		WHERE	DatabaseConfiguration.Property = t.Property
	SET @count = @@ROWCOUNT

	INSERT [dbo].[DatabaseConfiguration] (
		Property,
		Value,
		Created,
		LastUpdate
	)
		SELECT	Property,
			Value,
			Created,
			LastUpdate
		FROM	#DatabaseConfiguration AS t
		WHERE NOT EXISTS(	-- Current record doesn't exist
			SELECT * FROM [dbo].[DatabaseConfiguration]
			WHERE	DatabaseConfiguration.Property = t.Property
		)
	SET @count = @count + @@ROWCOUNT
	DROP TABLE #DatabaseConfiguration	-- Drop the temporary table
	COMMIT WORK
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[DatabaseConfigurationRemoveBatch]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[DatabaseConfigurationRemoveBatch]
GO

CREATE PROCEDURE [dbo].[DatabaseConfigurationRemoveBatch]
AS

	CREATE INDEX [TempDatabaseConfigurationDatabaseConfigurationRemoveBatch]
		ON #DatabaseConfiguration (Property)	

	-- Delete records from DatabaseConfiguration identified by fields of [TempDatabaseConfigurationDatabaseConfigurationRemoveBatch]
	DELETE [dbo].[DatabaseConfiguration]
	WHERE EXISTS(
			SELECT * FROM #DatabaseConfiguration AS t
			WHERE	DatabaseConfiguration.Property = t.Property
		)
	DROP TABLE #DatabaseConfiguration      -- Drop the temporary table
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[DatabaseConfigurationRemoveByProperty]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[DatabaseConfigurationRemoveByProperty]
GO
CREATE PROCEDURE [dbo].[DatabaseConfigurationRemoveByProperty]
	@Property		varchar(32)
AS
	DELETE	[dbo].[DatabaseConfiguration]
	WHERE	Property = @Property
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[DatabaseConfigurationRemoveAll]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[DatabaseConfigurationRemoveAll]
GO
CREATE PROCEDURE [dbo].[DatabaseConfigurationRemoveAll]
	
AS
	DELETE	[dbo].[DatabaseConfiguration]
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[TargetTypeGetByID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[TargetTypeGetByID]
GO
CREATE PROCEDURE [dbo].[TargetTypeGetByID]
	@TargetTypeID		int
AS
	SELECT	TargetTypeID,
		TargetTypeName
	FROM	[dbo].[TargetType]
	WHERE	TargetTypeID = @TargetTypeID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[TargetTypeGetByName]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[TargetTypeGetByName]
GO
CREATE PROCEDURE [dbo].[TargetTypeGetByName]
	@TargetTypeName		nvarchar(256)
AS
	SELECT	TargetTypeID,
		TargetTypeName
	FROM	[dbo].[TargetType]
	WHERE	TargetTypeName = @TargetTypeName
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[TargetTypeGetAll]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[TargetTypeGetAll]
GO
CREATE PROCEDURE [dbo].[TargetTypeGetAll]
AS
	SELECT	TargetTypeID,
		TargetTypeName
	FROM	[dbo].[TargetType]
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[TargetTypeBind]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[TargetTypeBind]
GO
CREATE PROCEDURE [dbo].[TargetTypeBind]
	@TargetTypeName		nvarchar(256)
AS
	DECLARE	@ID	int

	SELECT	@ID = TargetTypeID
	FROM	[dbo].[TargetType]
	WHERE	TargetTypeName = @TargetTypeName

	RETURN @ID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[OperatingSystemGetByName]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[OperatingSystemGetByName]
GO
CREATE PROCEDURE [dbo].[OperatingSystemGetByName]
	@OperatingSystemName	nvarchar(128)
AS
	SELECT	OperatingSystemID,
		OperatingSystemName,
		Category
	FROM	[dbo].[OperatingSystem]
	WHERE	OperatingSystemName = @OperatingSystemName
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[OperatingSystemGetByID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[OperatingSystemGetByID]
GO
CREATE PROCEDURE [dbo].[OperatingSystemGetByID]
	@OperatingSystemID	int
AS
	SELECT	OperatingSystemID,
		OperatingSystemName,
		Category
	FROM	[dbo].[OperatingSystem]
	WHERE	OperatingSystemID = @OperatingSystemID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[OperatingSystemGetAll]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[OperatingSystemGetAll]
GO
CREATE PROCEDURE [dbo].[OperatingSystemGetAll]
AS
	SELECT	OperatingSystemID,
		OperatingSystemName,
		Category
	FROM	[dbo].[OperatingSystem]
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[OperatingSystemAdd]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[OperatingSystemAdd]
GO
CREATE PROCEDURE [dbo].[OperatingSystemAdd]
	@OperatingSystemName	nvarchar(128),
	@Category		int = NULL
AS
	INSERT INTO  dbo.OperatingSystem (
		OperatingSystemName,
		Category
	)
	VALUES (
		@OperatingSystemName,
		@Category
	)
	RETURN SCOPE_IDENTITY()
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[OperatingSystemBind]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[OperatingSystemBind]
GO
CREATE PROCEDURE [dbo].[OperatingSystemBind]
	@OperatingSystemName	nvarchar(128),
	@Category		int = NULL
AS
	DECLARE	@ID	int

	SELECT	@ID = OperatingSystemID
	FROM	[dbo].[OperatingSystem]
	WHERE	OperatingSystemName = @OperatingSystemName

	IF @ID IS NULL
		EXEC @ID = OperatingSystemAdd @OperatingSystemName,
			@Category

	RETURN @ID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[OperatingSystemSchema]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[OperatingSystemSchema]
GO
CREATE PROCEDURE [dbo].[OperatingSystemSchema]
AS
	SELECT
	'IF OBJECT_ID(''tempdb..#OperatingSystem'') IS NULL' + CAST(0x0A AS CHAR(1)) +
	'	CREATE TABLE #OperatingSystem (' + CAST(0x0A AS CHAR(1)) +
	'		OperatingSystemID	int NULL,' + CAST(0x0A AS CHAR(1)) +
	'		OperatingSystemName	nvarchar(128) COLLATE database_default NOT NULL,' + CAST(0x0A AS CHAR(1)) +
	'		Category		int NULL' + CAST(0x0A AS CHAR(1)) +
	'	)' + CAST(0x0A AS CHAR(1)) +
	'ELSE' + CAST(0x0A AS CHAR(1)) +
	'	DELETE FROM #OperatingSystem' + CAST(0x0A AS CHAR(1)) +
	'' AS SQL
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[OperatingSystemTempAdd]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[OperatingSystemTempAdd]
GO
CREATE PROCEDURE dbo.[OperatingSystemTempAdd]
	@OperatingSystemID	int,
	@OperatingSystemName	nvarchar(128),
	@Category		int = NULL
AS
	INSERT INTO #OperatingSystem (
		OperatingSystemID,
		OperatingSystemName,
		Category
	)
	VALUES (
		@OperatingSystemID,
		@OperatingSystemName,
		@Category
	)
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[OperatingSystemAddBatch]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[OperatingSystemAddBatch]
GO
CREATE PROCEDURE dbo.[OperatingSystemAddBatch]
AS
	DECLARE @count int
	INSERT dbo.OperatingSystem (
		OperatingSystemName,
		Category
	)
		SELECT	OperatingSystemName,
			Category
		FROM #OperatingSystem
	SET @count = @@ROWCOUNT
	DROP TABLE #OperatingSystem	-- Drop temporary table
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[OperatingSystemUpdateByID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[OperatingSystemUpdateByID]
GO
CREATE PROCEDURE [dbo].[OperatingSystemUpdateByID]
	@OperatingSystemID	int,
	@OperatingSystemName	nvarchar(128),
	@Category		int = NULL
AS
	DECLARE	@ID	int
	SET @ID = 0

	UPDATE	[dbo].[OperatingSystem]
	SET	@ID = OperatingSystemID,
		OperatingSystemName = @OperatingSystemName,
		Category = @Category
	WHERE	OperatingSystemID = @OperatingSystemID
	RETURN @ID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[OperatingSystemUpdateBatchByID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[OperatingSystemUpdateBatchByID]
GO
CREATE PROCEDURE dbo.[OperatingSystemUpdateBatchByID]
AS
	DECLARE @count int

	CREATE INDEX [TempOperatingSystemID]
		ON #OperatingSystem (OperatingSystemID)

	UPDATE	[dbo].[OperatingSystem]
	SET	OperatingSystemName = t.OperatingSystemName,
		Category = t.Category
	FROM	#OperatingSystem AS t
	WHERE	OperatingSystem.OperatingSystemID = t.OperatingSystemID
	SET @count = @@ROWCOUNT
	DROP TABLE #OperatingSystem	-- Drop the temporary table
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[OperatingSystemUpdateByName]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[OperatingSystemUpdateByName]
GO
CREATE PROCEDURE [dbo].[OperatingSystemUpdateByName]
	@OperatingSystemName	nvarchar(128),
	@Category		int = NULL
AS
	DECLARE	@ID	int
	SET @ID = 0

	UPDATE	[dbo].[OperatingSystem]
	SET	@ID = OperatingSystemID,
		Category = @Category
	WHERE	OperatingSystemName = @OperatingSystemName
	RETURN @ID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[OperatingSystemUpdateBatchByName]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[OperatingSystemUpdateBatchByName]
GO
CREATE PROCEDURE dbo.[OperatingSystemUpdateBatchByName]
AS
	DECLARE @count int

	CREATE INDEX [TempOperatingSystemName]
		ON #OperatingSystem (OperatingSystemName)

	UPDATE	[dbo].[OperatingSystem]
	SET	Category = t.Category
	FROM	#OperatingSystem AS t
	WHERE	OperatingSystem.OperatingSystemName = t.OperatingSystemName
	SET @count = @@ROWCOUNT
	DROP TABLE #OperatingSystem	-- Drop the temporary table
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[OperatingSystemPutByName]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[OperatingSystemPutByName]
GO
CREATE PROCEDURE [dbo].[OperatingSystemPutByName]
	@OperatingSystemName	nvarchar(128),
	@Category		int = NULL
AS
	DECLARE @ID	int

	SELECT	@ID = OperatingSystemID
	FROM	OperatingSystem
	WHERE	OperatingSystemName = @OperatingSystemName

	IF @ID IS NULL
		EXEC @ID = OperatingSystemAdd @OperatingSystemName,
			@Category
	ELSE
		EXEC OperatingSystemUpdateByName @OperatingSystemName,
			@Category

	RETURN @ID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[OperatingSystemPutBatchByName]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[OperatingSystemPutBatchByName]
GO
CREATE PROCEDURE [dbo].[OperatingSystemPutBatchByName]
AS
	DECLARE @count AS int
	SET @count = 0

	CREATE INDEX [TempOperatingSystemName]
		ON #OperatingSystem (OperatingSystemName)

	BEGIN TRANSACTION
	UPDATE [dbo].[OperatingSystem]
		SET	Category = t.Category
		FROM	#OperatingSystem AS t
		WHERE	OperatingSystem.OperatingSystemName = t.OperatingSystemName
	SET @count = @@ROWCOUNT

	INSERT [dbo].[OperatingSystem] (
		OperatingSystemName,
		Category
	)
		SELECT	OperatingSystemName,
			Category
		FROM	#OperatingSystem AS t
		WHERE NOT EXISTS(	-- Current record doesn't exist
			SELECT * FROM [dbo].[OperatingSystem]
			WHERE	OperatingSystem.OperatingSystemName = t.OperatingSystemName
		)
	SET @count = @count + @@ROWCOUNT
	DROP TABLE #OperatingSystem	-- Drop the temporary table
	COMMIT WORK
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[OperatingSystemRemoveBatch]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[OperatingSystemRemoveBatch]
GO

CREATE PROCEDURE [dbo].[OperatingSystemRemoveBatch]
AS

	CREATE INDEX [TempOperatingSystemOperatingSystemRemoveBatch]
		ON #OperatingSystem (OperatingSystemID)	

	-- Delete records from OperatingSystem identified by fields of [TempOperatingSystemOperatingSystemRemoveBatch]
	DELETE [dbo].[OperatingSystem]
	WHERE EXISTS(
			SELECT * FROM #OperatingSystem AS t
			WHERE	OperatingSystem.OperatingSystemID = t.OperatingSystemID
		)
	DROP TABLE #OperatingSystem      -- Drop the temporary table
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[OperatingSystemRemoveByName]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[OperatingSystemRemoveByName]
GO
CREATE PROCEDURE [dbo].[OperatingSystemRemoveByName]
	@OperatingSystemName	nvarchar(128)
AS
	-- OperatingSystem deletes may fail due to non-cascading FKs:
	--	OperatingSystem by FK_OperatingSystem_Category
	--	Computer by FK_Computer_OperatingSystem
	--	NetworkDevice by FK_NetworkDevice_OperatingSystem
	DELETE	[dbo].[OperatingSystem]
	WHERE	OperatingSystemName = @OperatingSystemName
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[OperatingSystemRemoveAll]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[OperatingSystemRemoveAll]
GO
CREATE PROCEDURE [dbo].[OperatingSystemRemoveAll]
	
AS
	DELETE	[dbo].[OperatingSystem]
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[LanguageGetByLangCode3]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[LanguageGetByLangCode3]
GO
CREATE PROCEDURE [dbo].[LanguageGetByLangCode3]
	@LangCode3		nchar(3)
AS
	SELECT	LangCode3,
		LangCode2,
		EnglishName,
		LocalName,
		MSLanguageID
	FROM	[dbo].[Language]
	WHERE	LangCode3 = @LangCode3
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[LanguageGetAll]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[LanguageGetAll]
GO
CREATE PROCEDURE [dbo].[LanguageGetAll]
AS
	SELECT	LangCode3,
		LangCode2,
		EnglishName,
		LocalName,
		MSLanguageID
	FROM	[dbo].[Language]
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[LanguageAdd]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[LanguageAdd]
GO
CREATE PROCEDURE [dbo].[LanguageAdd]
	@LangCode3		nchar(3),
	@LangCode2		nchar(2) = NULL,
	@EnglishName		nvarchar(128),
	@LocalName		nvarchar(128) = NULL,
	@MSLanguageID		int = NULL
AS
	INSERT INTO  dbo.Language (
		LangCode3,
		LangCode2,
		EnglishName,
		LocalName,
		MSLanguageID
	)
	VALUES (
		@LangCode3,
		@LangCode2,
		@EnglishName,
		@LocalName,
		@MSLanguageID
	)
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[LanguageSchema]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[LanguageSchema]
GO
CREATE PROCEDURE [dbo].[LanguageSchema]
AS
	SELECT
	'IF OBJECT_ID(''tempdb..#Language'') IS NULL' + CAST(0x0A AS CHAR(1)) +
	'	CREATE TABLE #Language (' + CAST(0x0A AS CHAR(1)) +
	'		LangCode3		nchar(3) COLLATE database_default NOT NULL,' + CAST(0x0A AS CHAR(1)) +
	'		LangCode2		nchar(2) COLLATE database_default NULL,' + CAST(0x0A AS CHAR(1)) +
	'		EnglishName		nvarchar(128) COLLATE database_default NOT NULL,' + CAST(0x0A AS CHAR(1)) +
	'		LocalName		nvarchar(128) COLLATE database_default NULL,' + CAST(0x0A AS CHAR(1)) +
	'		MSLanguageID		int NULL' + CAST(0x0A AS CHAR(1)) +
	'	)' + CAST(0x0A AS CHAR(1)) +
	'ELSE' + CAST(0x0A AS CHAR(1)) +
	'	DELETE FROM #Language' + CAST(0x0A AS CHAR(1)) +
	'' AS SQL
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[LanguageTempAdd]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[LanguageTempAdd]
GO
CREATE PROCEDURE dbo.[LanguageTempAdd]
	@LangCode3		nchar(3),
	@LangCode2		nchar(2) = NULL,
	@EnglishName		nvarchar(128),
	@LocalName		nvarchar(128) = NULL,
	@MSLanguageID		int = NULL
AS
	INSERT INTO #Language (
		LangCode3,
		LangCode2,
		EnglishName,
		LocalName,
		MSLanguageID
	)
	VALUES (
		@LangCode3,
		@LangCode2,
		@EnglishName,
		@LocalName,
		@MSLanguageID
	)
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[LanguageAddBatch]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[LanguageAddBatch]
GO
CREATE PROCEDURE dbo.[LanguageAddBatch]
AS
	DECLARE @count int
	INSERT dbo.Language (
		LangCode3,
		LangCode2,
		EnglishName,
		LocalName,
		MSLanguageID
	)
		SELECT	LangCode3,
			LangCode2,
			EnglishName,
			LocalName,
			MSLanguageID
		FROM #Language
	SET @count = @@ROWCOUNT
	DROP TABLE #Language	-- Drop temporary table
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[LanguageUpdateByLangCode3]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[LanguageUpdateByLangCode3]
GO
CREATE PROCEDURE [dbo].[LanguageUpdateByLangCode3]
	@LangCode3		nchar(3),
	@LangCode2		nchar(2) = NULL,
	@EnglishName		nvarchar(128),
	@LocalName		nvarchar(128) = NULL,
	@MSLanguageID		int = NULL
AS
	UPDATE	[dbo].[Language]
	SET	LangCode2 = @LangCode2,
		EnglishName = @EnglishName,
		LocalName = @LocalName,
		MSLanguageID = @MSLanguageID
	WHERE	LangCode3 = @LangCode3
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[LanguageUpdateBatchByLangCode3]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[LanguageUpdateBatchByLangCode3]
GO
CREATE PROCEDURE dbo.[LanguageUpdateBatchByLangCode3]
AS
	DECLARE @count int

	CREATE INDEX [TempLanguageLangCode3]
		ON #Language (LangCode3)

	UPDATE	[dbo].[Language]
	SET	LangCode2 = t.LangCode2,
		EnglishName = t.EnglishName,
		LocalName = t.LocalName,
		MSLanguageID = t.MSLanguageID
	FROM	#Language AS t
	WHERE	Language.LangCode3 = t.LangCode3
	SET @count = @@ROWCOUNT
	DROP TABLE #Language	-- Drop the temporary table
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[LanguagePutByLangCode3]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[LanguagePutByLangCode3]
GO
CREATE PROCEDURE [dbo].[LanguagePutByLangCode3]
	@LangCode3		nchar(3),
	@LangCode2		nchar(2) = NULL,
	@EnglishName		nvarchar(128),
	@LocalName		nvarchar(128) = NULL,
	@MSLanguageID		int = NULL
AS
	IF NOT EXISTS(
		SELECT	1
		FROM	dbo.Language
		WHERE	LangCode3 = @LangCode3
	)
		EXEC LanguageAdd @LangCode3,
			@LangCode2,
			@EnglishName,
			@LocalName,
			@MSLanguageID
	ELSE
		EXEC LanguageUpdateByLangCode3 @LangCode3,
			@LangCode2,
			@EnglishName,
			@LocalName,
			@MSLanguageID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[LanguagePutBatchByLangCode3]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[LanguagePutBatchByLangCode3]
GO
CREATE PROCEDURE [dbo].[LanguagePutBatchByLangCode3]
AS
	DECLARE @count AS int
	SET @count = 0

	CREATE INDEX [TempLanguageLangCode3]
		ON #Language (LangCode3)

	BEGIN TRANSACTION
	UPDATE [dbo].[Language]
		SET	LangCode2 = t.LangCode2,
			EnglishName = t.EnglishName,
			LocalName = t.LocalName,
			MSLanguageID = t.MSLanguageID
		FROM	#Language AS t
		WHERE	Language.LangCode3 = t.LangCode3
	SET @count = @@ROWCOUNT

	INSERT [dbo].[Language] (
		LangCode3,
		LangCode2,
		EnglishName,
		LocalName,
		MSLanguageID
	)
		SELECT	LangCode3,
			LangCode2,
			EnglishName,
			LocalName,
			MSLanguageID
		FROM	#Language AS t
		WHERE NOT EXISTS(	-- Current record doesn't exist
			SELECT * FROM [dbo].[Language]
			WHERE	Language.LangCode3 = t.LangCode3
		)
	SET @count = @count + @@ROWCOUNT
	DROP TABLE #Language	-- Drop the temporary table
	COMMIT WORK
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[LanguageRemoveBatch]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[LanguageRemoveBatch]
GO

CREATE PROCEDURE [dbo].[LanguageRemoveBatch]
AS

	CREATE INDEX [TempLanguageLanguageRemoveBatch]
		ON #Language (LangCode3)	

	-- Delete records from Language identified by fields of [TempLanguageLanguageRemoveBatch]
	DELETE [dbo].[Language]
	WHERE EXISTS(
			SELECT * FROM #Language AS t
			WHERE	Language.LangCode3 = t.LangCode3
		)
	DROP TABLE #Language      -- Drop the temporary table
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[LanguageRemoveByLangCode3]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[LanguageRemoveByLangCode3]
GO
CREATE PROCEDURE [dbo].[LanguageRemoveByLangCode3]
	@LangCode3		nchar(3)
AS
	-- Language deletes cascade to:
	--	Locale by FK_Locale_Language
	--		PackageVersionLocale by FK_PackageVersionLocale_Locale
	DELETE	[dbo].[Language]
	WHERE	LangCode3 = @LangCode3
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[LanguageRemoveAll]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[LanguageRemoveAll]
GO
CREATE PROCEDURE [dbo].[LanguageRemoveAll]
	
AS
	DELETE	[dbo].[Language]
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[CountryGetByCode]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[CountryGetByCode]
GO
CREATE PROCEDURE [dbo].[CountryGetByCode]
	@CountryCode		nchar(2)
AS
	SELECT	CountryCode,
		[Name]
	FROM	[dbo].[Country]
	WHERE	CountryCode = @CountryCode
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[CountryGetAllByName]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[CountryGetAllByName]
GO
CREATE PROCEDURE [dbo].[CountryGetAllByName]
	@Name			nvarchar(128)
AS
	SELECT	CountryCode,
		[Name]
	FROM	[dbo].[Country]
	WHERE	[Name] = @Name
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[CountryGetAll]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[CountryGetAll]
GO
CREATE PROCEDURE [dbo].[CountryGetAll]
AS
	SELECT	CountryCode,
		[Name]
	FROM	[dbo].[Country]
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[CountryAdd]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[CountryAdd]
GO
CREATE PROCEDURE [dbo].[CountryAdd]
	@CountryCode		nchar(2),
	@Name			nvarchar(128)
AS
	INSERT INTO  dbo.Country (
		CountryCode,
		[Name]
	)
	VALUES (
		@CountryCode,
		@Name
	)
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[CountrySchema]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[CountrySchema]
GO
CREATE PROCEDURE [dbo].[CountrySchema]
AS
	SELECT
	'IF OBJECT_ID(''tempdb..#Country'') IS NULL' + CAST(0x0A AS CHAR(1)) +
	'	CREATE TABLE #Country (' + CAST(0x0A AS CHAR(1)) +
	'		CountryCode		nchar(2) COLLATE database_default NOT NULL,' + CAST(0x0A AS CHAR(1)) +
	'		[Name]			nvarchar(128) COLLATE database_default NOT NULL' + CAST(0x0A AS CHAR(1)) +
	'	)' + CAST(0x0A AS CHAR(1)) +
	'ELSE' + CAST(0x0A AS CHAR(1)) +
	'	DELETE FROM #Country' + CAST(0x0A AS CHAR(1)) +
	'' AS SQL
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[CountryTempAdd]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[CountryTempAdd]
GO
CREATE PROCEDURE dbo.[CountryTempAdd]
	@CountryCode		nchar(2),
	@Name			nvarchar(128)
AS
	INSERT INTO #Country (
		CountryCode,
		[Name]
	)
	VALUES (
		@CountryCode,
		@Name
	)
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[CountryAddBatch]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[CountryAddBatch]
GO
CREATE PROCEDURE dbo.[CountryAddBatch]
AS
	DECLARE @count int
	INSERT dbo.Country (
		CountryCode,
		[Name]
	)
		SELECT	CountryCode,
			[Name]
		FROM #Country
	SET @count = @@ROWCOUNT
	DROP TABLE #Country	-- Drop temporary table
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[CountryUpdateByCode]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[CountryUpdateByCode]
GO
CREATE PROCEDURE [dbo].[CountryUpdateByCode]
	@CountryCode		nchar(2),
	@Name			nvarchar(128)
AS
	UPDATE	[dbo].[Country]
	SET	[Name] = @Name
	WHERE	CountryCode = @CountryCode
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[CountryUpdateBatchByCode]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[CountryUpdateBatchByCode]
GO
CREATE PROCEDURE dbo.[CountryUpdateBatchByCode]
AS
	DECLARE @count int

	CREATE INDEX [TempCountryCode]
		ON #Country (CountryCode)

	UPDATE	[dbo].[Country]
	SET	[Name] = t.[Name]
	FROM	#Country AS t
	WHERE	Country.CountryCode = t.CountryCode
	SET @count = @@ROWCOUNT
	DROP TABLE #Country	-- Drop the temporary table
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[CountryPutByCode]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[CountryPutByCode]
GO
CREATE PROCEDURE [dbo].[CountryPutByCode]
	@CountryCode		nchar(2),
	@Name			nvarchar(128)
AS
	IF NOT EXISTS(
		SELECT	1
		FROM	dbo.Country
		WHERE	CountryCode = @CountryCode
	)
		EXEC CountryAdd @CountryCode,
			@Name
	ELSE
		EXEC CountryUpdateByCode @CountryCode,
			@Name
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[CountryPutBatchByCode]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[CountryPutBatchByCode]
GO
CREATE PROCEDURE [dbo].[CountryPutBatchByCode]
AS
	DECLARE @count AS int
	SET @count = 0

	CREATE INDEX [TempCountryCode]
		ON #Country (CountryCode)

	BEGIN TRANSACTION
	UPDATE [dbo].[Country]
		SET	[Name] = t.[Name]
		FROM	#Country AS t
		WHERE	Country.CountryCode = t.CountryCode
	SET @count = @@ROWCOUNT

	INSERT [dbo].[Country] (
		CountryCode,
		[Name]
	)
		SELECT	CountryCode,
			[Name]
		FROM	#Country AS t
		WHERE NOT EXISTS(	-- Current record doesn't exist
			SELECT * FROM [dbo].[Country]
			WHERE	Country.CountryCode = t.CountryCode
		)
	SET @count = @count + @@ROWCOUNT
	DROP TABLE #Country	-- Drop the temporary table
	COMMIT WORK
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[CountryRemoveBatch]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[CountryRemoveBatch]
GO

CREATE PROCEDURE [dbo].[CountryRemoveBatch]
AS

	CREATE INDEX [TempCountryCountryRemoveBatch]
		ON #Country (CountryCode)	

	-- Delete records from Country identified by fields of [TempCountryCountryRemoveBatch]
	DELETE [dbo].[Country]
	WHERE EXISTS(
			SELECT * FROM #Country AS t
			WHERE	Country.CountryCode = t.CountryCode
		)
	DROP TABLE #Country      -- Drop the temporary table
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[CountryRemoveByCode]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[CountryRemoveByCode]
GO
CREATE PROCEDURE [dbo].[CountryRemoveByCode]
	@CountryCode		nchar(2)
AS
	-- Country deletes cascade to:
	--	Locale by FK_Locale_Country
	--		PackageVersionLocale by FK_PackageVersionLocale_Locale
	DELETE	[dbo].[Country]
	WHERE	CountryCode = @CountryCode
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[CountryRemoveAll]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[CountryRemoveAll]
GO
CREATE PROCEDURE [dbo].[CountryRemoveAll]
	
AS
	DELETE	[dbo].[Country]
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[LocaleGetByCode]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[LocaleGetByCode]
GO
CREATE PROCEDURE [dbo].[LocaleGetByCode]
	@LocaleCode		nvarchar(6)
AS
	SELECT	LocaleCode,
		LangCode3,
		CountryCode,
		LocaleName,
		MSLocaleID
	FROM	[dbo].[Locale]
	WHERE	LocaleCode = @LocaleCode
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[LocaleGetByLangCode3CountryCode]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[LocaleGetByLangCode3CountryCode]
GO
CREATE PROCEDURE [dbo].[LocaleGetByLangCode3CountryCode]
	@LangCode3		nchar(3),
	@CountryCode		nchar(2) = NULL
AS
	SELECT	LocaleCode,
		LangCode3,
		CountryCode,
		LocaleName,
		MSLocaleID
	FROM	[dbo].[Locale]
	WHERE	LangCode3 = @LangCode3
	  AND	(CountryCode = @CountryCode OR (CountryCode IS NULL AND @CountryCode IS NULL))
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[LocaleGetAllByLangCode3]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[LocaleGetAllByLangCode3]
GO
CREATE PROCEDURE [dbo].[LocaleGetAllByLangCode3]
	@LangCode3		nchar(3)
AS
	SELECT	LocaleCode,
		LangCode3,
		CountryCode,
		LocaleName,
		MSLocaleID
	FROM	[dbo].[Locale]
	WHERE	LangCode3 = @LangCode3
	ORDER BY CountryCode
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[LocaleGetAll]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[LocaleGetAll]
GO
CREATE PROCEDURE [dbo].[LocaleGetAll]
AS
	SELECT	LocaleCode,
		LangCode3,
		CountryCode,
		LocaleName,
		MSLocaleID
	FROM	[dbo].[Locale]
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[LocaleAdd]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[LocaleAdd]
GO
CREATE PROCEDURE [dbo].[LocaleAdd]
	@LocaleCode		nvarchar(6),
	@LangCode3		nchar(3),
	@CountryCode		nchar(2) = NULL,
	@LocaleName		nvarchar(128),
	@MSLocaleID		int = NULL
AS
	INSERT INTO  dbo.Locale (
		LocaleCode,
		LangCode3,
		CountryCode,
		LocaleName,
		MSLocaleID
	)
	VALUES (
		@LocaleCode,
		@LangCode3,
		@CountryCode,
		@LocaleName,
		@MSLocaleID
	)
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[LocaleSchema]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[LocaleSchema]
GO
CREATE PROCEDURE [dbo].[LocaleSchema]
AS
	SELECT
	'IF OBJECT_ID(''tempdb..#Locale'') IS NULL' + CAST(0x0A AS CHAR(1)) +
	'	CREATE TABLE #Locale (' + CAST(0x0A AS CHAR(1)) +
	'		LocaleCode		nvarchar(6) COLLATE database_default NOT NULL,' + CAST(0x0A AS CHAR(1)) +
	'		LangCode3		nchar(3) COLLATE database_default NOT NULL,' + CAST(0x0A AS CHAR(1)) +
	'		CountryCode		nchar(2) COLLATE database_default NULL,' + CAST(0x0A AS CHAR(1)) +
	'		LocaleName		nvarchar(128) COLLATE database_default NOT NULL,' + CAST(0x0A AS CHAR(1)) +
	'		MSLocaleID		int NULL' + CAST(0x0A AS CHAR(1)) +
	'	)' + CAST(0x0A AS CHAR(1)) +
	'ELSE' + CAST(0x0A AS CHAR(1)) +
	'	DELETE FROM #Locale' + CAST(0x0A AS CHAR(1)) +
	'' AS SQL
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[LocaleTempAdd]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[LocaleTempAdd]
GO
CREATE PROCEDURE dbo.[LocaleTempAdd]
	@LocaleCode		nvarchar(6),
	@LangCode3		nchar(3),
	@CountryCode		nchar(2) = NULL,
	@LocaleName		nvarchar(128),
	@MSLocaleID		int = NULL
AS
	INSERT INTO #Locale (
		LocaleCode,
		LangCode3,
		CountryCode,
		LocaleName,
		MSLocaleID
	)
	VALUES (
		@LocaleCode,
		@LangCode3,
		@CountryCode,
		@LocaleName,
		@MSLocaleID
	)
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[LocaleAddBatch]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[LocaleAddBatch]
GO
CREATE PROCEDURE dbo.[LocaleAddBatch]
AS
	DECLARE @count int
	INSERT dbo.Locale (
		LocaleCode,
		LangCode3,
		CountryCode,
		LocaleName,
		MSLocaleID
	)
		SELECT	LocaleCode,
			LangCode3,
			CountryCode,
			LocaleName,
			MSLocaleID
		FROM #Locale
	SET @count = @@ROWCOUNT
	DROP TABLE #Locale	-- Drop temporary table
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[LocaleUpdateByCode]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[LocaleUpdateByCode]
GO
CREATE PROCEDURE [dbo].[LocaleUpdateByCode]
	@LocaleCode		nvarchar(6),
	@LangCode3		nchar(3),
	@CountryCode		nchar(2) = NULL,
	@LocaleName		nvarchar(128),
	@MSLocaleID		int = NULL
AS
	UPDATE	[dbo].[Locale]
	SET	LangCode3 = @LangCode3,
		CountryCode = @CountryCode,
		LocaleName = @LocaleName,
		MSLocaleID = @MSLocaleID
	WHERE	LocaleCode = @LocaleCode
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[LocaleUpdateBatchByCode]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[LocaleUpdateBatchByCode]
GO
CREATE PROCEDURE dbo.[LocaleUpdateBatchByCode]
AS
	DECLARE @count int

	CREATE INDEX [TempLocaleCode]
		ON #Locale (LocaleCode)

	UPDATE	[dbo].[Locale]
	SET	LangCode3 = t.LangCode3,
		CountryCode = t.CountryCode,
		LocaleName = t.LocaleName,
		MSLocaleID = t.MSLocaleID
	FROM	#Locale AS t
	WHERE	Locale.LocaleCode = t.LocaleCode
	SET @count = @@ROWCOUNT
	DROP TABLE #Locale	-- Drop the temporary table
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[LocalePutByCode]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[LocalePutByCode]
GO
CREATE PROCEDURE [dbo].[LocalePutByCode]
	@LocaleCode		nvarchar(6),
	@LangCode3		nchar(3),
	@CountryCode		nchar(2) = NULL,
	@LocaleName		nvarchar(128),
	@MSLocaleID		int = NULL
AS
	IF NOT EXISTS(
		SELECT	1
		FROM	dbo.Locale
		WHERE	LocaleCode = @LocaleCode
	)
		EXEC LocaleAdd @LocaleCode,
			@LangCode3,
			@CountryCode,
			@LocaleName,
			@MSLocaleID
	ELSE
		EXEC LocaleUpdateByCode @LocaleCode,
			@LangCode3,
			@CountryCode,
			@LocaleName,
			@MSLocaleID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[LocalePutBatchByCode]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[LocalePutBatchByCode]
GO
CREATE PROCEDURE [dbo].[LocalePutBatchByCode]
AS
	DECLARE @count AS int
	SET @count = 0

	CREATE INDEX [TempLocaleCode]
		ON #Locale (LocaleCode)

	BEGIN TRANSACTION
	UPDATE [dbo].[Locale]
		SET	LangCode3 = t.LangCode3,
			CountryCode = t.CountryCode,
			LocaleName = t.LocaleName,
			MSLocaleID = t.MSLocaleID
		FROM	#Locale AS t
		WHERE	Locale.LocaleCode = t.LocaleCode
	SET @count = @@ROWCOUNT

	INSERT [dbo].[Locale] (
		LocaleCode,
		LangCode3,
		CountryCode,
		LocaleName,
		MSLocaleID
	)
		SELECT	LocaleCode,
			LangCode3,
			CountryCode,
			LocaleName,
			MSLocaleID
		FROM	#Locale AS t
		WHERE NOT EXISTS(	-- Current record doesn't exist
			SELECT * FROM [dbo].[Locale]
			WHERE	Locale.LocaleCode = t.LocaleCode
		)
	SET @count = @count + @@ROWCOUNT
	DROP TABLE #Locale	-- Drop the temporary table
	COMMIT WORK
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[LocaleRemoveBatch]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[LocaleRemoveBatch]
GO

CREATE PROCEDURE [dbo].[LocaleRemoveBatch]
AS

	CREATE INDEX [TempLocaleLocaleRemoveBatch]
		ON #Locale (LocaleCode)	

	-- Delete records from Locale identified by fields of [TempLocaleLocaleRemoveBatch]
	DELETE [dbo].[Locale]
	WHERE EXISTS(
			SELECT * FROM #Locale AS t
			WHERE	Locale.LocaleCode = t.LocaleCode
		)
	DROP TABLE #Locale      -- Drop the temporary table
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[LocaleRemoveByCode]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[LocaleRemoveByCode]
GO
CREATE PROCEDURE [dbo].[LocaleRemoveByCode]
	@LocaleCode		nvarchar(6)
AS
	-- Locale deletes cascade to:
	--	PackageVersionLocale by FK_PackageVersionLocale_Locale
	DELETE	[dbo].[Locale]
	WHERE	LocaleCode = @LocaleCode
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[LocaleRemoveAll]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[LocaleRemoveAll]
GO
CREATE PROCEDURE [dbo].[LocaleRemoveAll]
	
AS
	DELETE	[dbo].[Locale]
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[NetworkLocationGetByID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[NetworkLocationGetByID]
GO
CREATE PROCEDURE [dbo].[NetworkLocationGetByID]
	@NetworkLocationID	int
AS
	SELECT	NetworkLocationID,
		[Name],
		DN,
		AutoPopulated,
		Enabled,
		DomainID
	FROM	[dbo].[NetworkLocation]
	WHERE	NetworkLocationID = @NetworkLocationID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[NetworkLocationGetByDN]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[NetworkLocationGetByDN]
GO
CREATE PROCEDURE [dbo].[NetworkLocationGetByDN]
	@DN			nvarchar(1024) = NULL
AS
	SELECT	NetworkLocationID,
		[Name],
		DN,
		AutoPopulated,
		Enabled,
		DomainID
	FROM	[dbo].[NetworkLocation]
	WHERE	(DN = @DN OR (DN IS NULL AND @DN IS NULL))
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[NetworkLocationGetByName]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[NetworkLocationGetByName]
GO
CREATE PROCEDURE [dbo].[NetworkLocationGetByName]
	@Name			nvarchar(256)
AS
	SELECT	NetworkLocationID,
		[Name],
		DN,
		AutoPopulated,
		Enabled,
		DomainID
	FROM	[dbo].[NetworkLocation]
	WHERE	[Name] = @Name
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[NetworkLocationGetAllByDomainID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[NetworkLocationGetAllByDomainID]
GO
CREATE PROCEDURE [dbo].[NetworkLocationGetAllByDomainID]
	@DomainID		int
AS
	SELECT	NetworkLocationID,
		[Name],
		DN,
		AutoPopulated,
		Enabled,
		DomainID
	FROM	[dbo].[NetworkLocation]
	WHERE	DomainID = @DomainID
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[NetworkLocationGetAll]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[NetworkLocationGetAll]
GO
CREATE PROCEDURE [dbo].[NetworkLocationGetAll]
AS
	SELECT	NetworkLocationID,
		[Name],
		DN,
		AutoPopulated,
		Enabled,
		DomainID
	FROM	[dbo].[NetworkLocation]
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[NetworkLocationAdd]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[NetworkLocationAdd]
GO
CREATE PROCEDURE [dbo].[NetworkLocationAdd]
	@Name			nvarchar(256),
	@DN			nvarchar(1024) = NULL,
	@AutoPopulated		bit = 0,
	@Enabled		bit = 1,
	@DomainID		int
AS
	INSERT INTO  dbo.NetworkLocation (
		[Name],
		DN,
		AutoPopulated,
		Enabled,
		DomainID
	)
	VALUES (
		@Name,
		@DN,
		@AutoPopulated,
		@Enabled,
		@DomainID
	)
	RETURN SCOPE_IDENTITY()
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[NetworkLocationBind]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[NetworkLocationBind]
GO
CREATE PROCEDURE [dbo].[NetworkLocationBind]
	@Name			nvarchar(256),
	@DN			nvarchar(1024) = NULL,
	@AutoPopulated		bit = 0,
	@Enabled		bit = 1,
	@DomainID		int
AS
	DECLARE	@ID	int

	SELECT	@ID = NetworkLocationID
	FROM	[dbo].[NetworkLocation]
	WHERE	[Name] = @Name

	IF @ID IS NULL
		EXEC @ID = NetworkLocationAdd @Name,
			@DN,
			@AutoPopulated,
			@Enabled,
			@DomainID

	RETURN @ID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[NetworkLocationSchema]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[NetworkLocationSchema]
GO
CREATE PROCEDURE [dbo].[NetworkLocationSchema]
AS
	SELECT
	'IF OBJECT_ID(''tempdb..#NetworkLocation'') IS NULL' + CAST(0x0A AS CHAR(1)) +
	'	CREATE TABLE #NetworkLocation (' + CAST(0x0A AS CHAR(1)) +
	'		NetworkLocationID	int NULL,' + CAST(0x0A AS CHAR(1)) +
	'		[Name]			nvarchar(256) COLLATE database_default NOT NULL,' + CAST(0x0A AS CHAR(1)) +
	'		DN			nvarchar(1024) COLLATE database_default NULL,' + CAST(0x0A AS CHAR(1)) +
	'		AutoPopulated		bit NOT NULL DEFAULT 0,' + CAST(0x0A AS CHAR(1)) +
	'		Enabled			bit NOT NULL DEFAULT 1,' + CAST(0x0A AS CHAR(1)) +
	'		DomainID		int NOT NULL' + CAST(0x0A AS CHAR(1)) +
	'	)' + CAST(0x0A AS CHAR(1)) +
	'ELSE' + CAST(0x0A AS CHAR(1)) +
	'	DELETE FROM #NetworkLocation' + CAST(0x0A AS CHAR(1)) +
	'' AS SQL
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[NetworkLocationTempAdd]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[NetworkLocationTempAdd]
GO
CREATE PROCEDURE dbo.[NetworkLocationTempAdd]
	@NetworkLocationID	int,
	@Name			nvarchar(256),
	@DN			nvarchar(1024) = NULL,
	@AutoPopulated		bit = 0,
	@Enabled		bit = 1,
	@DomainID		int
AS
	INSERT INTO #NetworkLocation (
		NetworkLocationID,
		[Name],
		DN,
		AutoPopulated,
		Enabled,
		DomainID
	)
	VALUES (
		@NetworkLocationID,
		@Name,
		@DN,
		@AutoPopulated,
		@Enabled,
		@DomainID
	)
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[NetworkLocationAddBatch]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[NetworkLocationAddBatch]
GO
CREATE PROCEDURE dbo.[NetworkLocationAddBatch]
AS
	DECLARE @count int
	INSERT dbo.NetworkLocation (
		[Name],
		DN,
		AutoPopulated,
		Enabled,
		DomainID
	)
		SELECT	[Name],
			DN,
			AutoPopulated,
			Enabled,
			DomainID
		FROM #NetworkLocation
	SET @count = @@ROWCOUNT
	DROP TABLE #NetworkLocation	-- Drop temporary table
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[NetworkLocationUpdateByID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[NetworkLocationUpdateByID]
GO
CREATE PROCEDURE [dbo].[NetworkLocationUpdateByID]
	@NetworkLocationID	int,
	@Name			nvarchar(256),
	@DN			nvarchar(1024) = NULL,
	@AutoPopulated		bit = 0,
	@Enabled		bit = 1,
	@DomainID		int
AS
	DECLARE	@ID	int
	SET @ID = 0

	UPDATE	[dbo].[NetworkLocation]
	SET	@ID = NetworkLocationID,
		[Name] = @Name,
		DN = @DN,
		AutoPopulated = @AutoPopulated,
		Enabled = @Enabled,
		DomainID = @DomainID
	WHERE	NetworkLocationID = @NetworkLocationID
	RETURN @ID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[NetworkLocationUpdateBatchByID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[NetworkLocationUpdateBatchByID]
GO
CREATE PROCEDURE dbo.[NetworkLocationUpdateBatchByID]
AS
	DECLARE @count int

	CREATE INDEX [TempNetworkLocationID]
		ON #NetworkLocation (NetworkLocationID)

	UPDATE	[dbo].[NetworkLocation]
	SET	[Name] = t.[Name],
		DN = t.DN,
		AutoPopulated = t.AutoPopulated,
		Enabled = t.Enabled,
		DomainID = t.DomainID
	FROM	#NetworkLocation AS t
	WHERE	NetworkLocation.NetworkLocationID = t.NetworkLocationID
	SET @count = @@ROWCOUNT
	DROP TABLE #NetworkLocation	-- Drop the temporary table
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[NetworkLocationUpdateByName]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[NetworkLocationUpdateByName]
GO
CREATE PROCEDURE [dbo].[NetworkLocationUpdateByName]
	@Name			nvarchar(256),
	@DN			nvarchar(1024) = NULL,
	@AutoPopulated		bit = 0,
	@Enabled		bit = 1,
	@DomainID		int
AS
	DECLARE	@ID	int
	SET @ID = 0

	UPDATE	[dbo].[NetworkLocation]
	SET	@ID = NetworkLocationID,
		DN = @DN,
		AutoPopulated = @AutoPopulated,
		Enabled = @Enabled,
		DomainID = @DomainID
	WHERE	[Name] = @Name
	RETURN @ID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[NetworkLocationUpdateBatchByName]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[NetworkLocationUpdateBatchByName]
GO
CREATE PROCEDURE dbo.[NetworkLocationUpdateBatchByName]
AS
	DECLARE @count int

	CREATE INDEX [TempNetworkLocationName]
		ON #NetworkLocation ([Name])

	UPDATE	[dbo].[NetworkLocation]
	SET	DN = t.DN,
		AutoPopulated = t.AutoPopulated,
		Enabled = t.Enabled,
		DomainID = t.DomainID
	FROM	#NetworkLocation AS t
	WHERE	NetworkLocation.[Name] = t.[Name]
	SET @count = @@ROWCOUNT
	DROP TABLE #NetworkLocation	-- Drop the temporary table
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[NetworkLocationPutByName]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[NetworkLocationPutByName]
GO
CREATE PROCEDURE [dbo].[NetworkLocationPutByName]
	@Name			nvarchar(256),
	@DN			nvarchar(1024) = NULL,
	@AutoPopulated		bit = 0,
	@Enabled		bit = 1,
	@DomainID		int
AS
	DECLARE @ID	int

	SELECT	@ID = NetworkLocationID
	FROM	NetworkLocation
	WHERE	[Name] = @Name

	IF @ID IS NULL
		EXEC @ID = NetworkLocationAdd @Name,
			@DN,
			@AutoPopulated,
			@Enabled,
			@DomainID
	ELSE
		EXEC NetworkLocationUpdateByName @Name,
			@DN,
			@AutoPopulated,
			@Enabled,
			@DomainID

	RETURN @ID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[NetworkLocationPutBatchByName]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[NetworkLocationPutBatchByName]
GO
CREATE PROCEDURE [dbo].[NetworkLocationPutBatchByName]
AS
	DECLARE @count AS int
	SET @count = 0

	CREATE INDEX [TempNetworkLocationName]
		ON #NetworkLocation ([Name])

	BEGIN TRANSACTION
	UPDATE [dbo].[NetworkLocation]
		SET	DN = t.DN,
			AutoPopulated = t.AutoPopulated,
			Enabled = t.Enabled,
			DomainID = t.DomainID
		FROM	#NetworkLocation AS t
		WHERE	NetworkLocation.[Name] = t.[Name]
	SET @count = @@ROWCOUNT

	INSERT [dbo].[NetworkLocation] (
		[Name],
		DN,
		AutoPopulated,
		Enabled,
		DomainID
	)
		SELECT	[Name],
			DN,
			AutoPopulated,
			Enabled,
			DomainID
		FROM	#NetworkLocation AS t
		WHERE NOT EXISTS(	-- Current record doesn't exist
			SELECT * FROM [dbo].[NetworkLocation]
			WHERE	NetworkLocation.[Name] = t.[Name]
		)
	SET @count = @count + @@ROWCOUNT
	DROP TABLE #NetworkLocation	-- Drop the temporary table
	COMMIT WORK
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[NetworkLocationRemoveBatch]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[NetworkLocationRemoveBatch]
GO

CREATE PROCEDURE [dbo].[NetworkLocationRemoveBatch]
AS

	CREATE INDEX [TempNetworkLocationNetworkLocationRemoveBatch]
		ON #NetworkLocation (NetworkLocationID)	

	-- Delete records from NetworkLocation identified by fields of [TempNetworkLocationNetworkLocationRemoveBatch]
	DELETE [dbo].[NetworkLocation]
	WHERE EXISTS(
			SELECT * FROM #NetworkLocation AS t
			WHERE	NetworkLocation.NetworkLocationID = t.NetworkLocationID
		)
	DROP TABLE #NetworkLocation      -- Drop the temporary table
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[NetworkLocationRemoveByID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[NetworkLocationRemoveByID]
GO
CREATE PROCEDURE [dbo].[NetworkLocationRemoveByID]
	@NetworkLocationID	int
AS
	-- NetworkLocation deletes cascade to:
	--	Subnet by FK_Subnet_NetworkLocation
	DELETE	[dbo].[NetworkLocation]
	WHERE	NetworkLocationID = @NetworkLocationID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[NetworkLocationRemoveByDN]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[NetworkLocationRemoveByDN]
GO
CREATE PROCEDURE [dbo].[NetworkLocationRemoveByDN]
	@DN			nvarchar(1024) = NULL
AS
	-- NetworkLocation deletes cascade to:
	--	Subnet by FK_Subnet_NetworkLocation
	DELETE	[dbo].[NetworkLocation]
	WHERE	(DN = @DN OR (DN IS NULL AND @DN IS NULL))
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[NetworkLocationRemoveByName]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[NetworkLocationRemoveByName]
GO
CREATE PROCEDURE [dbo].[NetworkLocationRemoveByName]
	@Name			nvarchar(256)
AS
	-- NetworkLocation deletes cascade to:
	--	Subnet by FK_Subnet_NetworkLocation
	DELETE	[dbo].[NetworkLocation]
	WHERE	[Name] = @Name
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[NetworkLocationRemoveAllByDomainID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[NetworkLocationRemoveAllByDomainID]
GO
CREATE PROCEDURE [dbo].[NetworkLocationRemoveAllByDomainID]
	@DomainID		int
AS
	DELETE	[dbo].[NetworkLocation]
	WHERE	DomainID = @DomainID
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[NetworkLocationRemoveAll]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[NetworkLocationRemoveAll]
GO
CREATE PROCEDURE [dbo].[NetworkLocationRemoveAll]
	
AS
	DELETE	[dbo].[NetworkLocation]
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[SubnetGetByID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[SubnetGetByID]
GO
CREATE PROCEDURE [dbo].[SubnetGetByID]
	@SubnetID		int
AS
	SELECT	SubnetID,
		IPSubnet,
		IPSubnetMask,
		NetworkLocationID,
		AutoPopulated,
		Enabled
	FROM	[dbo].[Subnet]
	WHERE	SubnetID = @SubnetID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[SubnetGetByIPSubnetIPSubnetMaskNetworkLocationID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[SubnetGetByIPSubnetIPSubnetMaskNetworkLocationID]
GO
CREATE PROCEDURE [dbo].[SubnetGetByIPSubnetIPSubnetMaskNetworkLocationID]
	@IPSubnet		nvarchar(64),
	@IPSubnetMask		nvarchar(64),
	@NetworkLocationID	int
AS
	SELECT	SubnetID,
		IPSubnet,
		IPSubnetMask,
		NetworkLocationID,
		AutoPopulated,
		Enabled
	FROM	[dbo].[Subnet]
	WHERE	IPSubnet = @IPSubnet
	  AND	IPSubnetMask = @IPSubnetMask
	  AND	NetworkLocationID = @NetworkLocationID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[SubnetGetAllByIPSubnetIPSubnetMask]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[SubnetGetAllByIPSubnetIPSubnetMask]
GO
CREATE PROCEDURE [dbo].[SubnetGetAllByIPSubnetIPSubnetMask]
	@IPSubnet		nvarchar(64),
	@IPSubnetMask		nvarchar(64)
AS
	SELECT	SubnetID,
		IPSubnet,
		IPSubnetMask,
		NetworkLocationID,
		AutoPopulated,
		Enabled
	FROM	[dbo].[Subnet]
	WHERE	IPSubnet = @IPSubnet
	  AND	IPSubnetMask = @IPSubnetMask
	ORDER BY NetworkLocationID
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[SubnetGetAllByIPSubnet]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[SubnetGetAllByIPSubnet]
GO
CREATE PROCEDURE [dbo].[SubnetGetAllByIPSubnet]
	@IPSubnet		nvarchar(64)
AS
	SELECT	SubnetID,
		IPSubnet,
		IPSubnetMask,
		NetworkLocationID,
		AutoPopulated,
		Enabled
	FROM	[dbo].[Subnet]
	WHERE	IPSubnet = @IPSubnet
	ORDER BY IPSubnetMask, NetworkLocationID
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[SubnetGetAllByNetworkLocationID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[SubnetGetAllByNetworkLocationID]
GO
CREATE PROCEDURE [dbo].[SubnetGetAllByNetworkLocationID]
	@NetworkLocationID	int
AS
	SELECT	SubnetID,
		IPSubnet,
		IPSubnetMask,
		NetworkLocationID,
		AutoPopulated,
		Enabled
	FROM	[dbo].[Subnet]
	WHERE	NetworkLocationID = @NetworkLocationID
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[SubnetGetAll]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[SubnetGetAll]
GO
CREATE PROCEDURE [dbo].[SubnetGetAll]
AS
	SELECT	SubnetID,
		IPSubnet,
		IPSubnetMask,
		NetworkLocationID,
		AutoPopulated,
		Enabled
	FROM	[dbo].[Subnet]
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[SubnetAdd]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[SubnetAdd]
GO
CREATE PROCEDURE [dbo].[SubnetAdd]
	@IPSubnet		nvarchar(64),
	@IPSubnetMask		nvarchar(64),
	@NetworkLocationID	int,
	@AutoPopulated		bit = 0,
	@Enabled		bit = 1
AS
	INSERT INTO  dbo.Subnet (
		IPSubnet,
		IPSubnetMask,
		NetworkLocationID,
		AutoPopulated,
		Enabled
	)
	VALUES (
		@IPSubnet,
		@IPSubnetMask,
		@NetworkLocationID,
		@AutoPopulated,
		@Enabled
	)
	RETURN SCOPE_IDENTITY()
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[SubnetBind]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[SubnetBind]
GO
CREATE PROCEDURE [dbo].[SubnetBind]
	@IPSubnet		nvarchar(64),
	@IPSubnetMask		nvarchar(64),
	@NetworkLocationID	int,
	@AutoPopulated		bit = 0,
	@Enabled		bit = 1
AS
	DECLARE	@ID	int

	SELECT	@ID = SubnetID
	FROM	[dbo].[Subnet]
	WHERE	IPSubnet = @IPSubnet
	  AND	IPSubnetMask = @IPSubnetMask
	  AND	NetworkLocationID = @NetworkLocationID

	IF @ID IS NULL
		EXEC @ID = SubnetAdd @IPSubnet,
			@IPSubnetMask,
			@NetworkLocationID,
			@AutoPopulated,
			@Enabled

	RETURN @ID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[SubnetSchema]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[SubnetSchema]
GO
CREATE PROCEDURE [dbo].[SubnetSchema]
AS
	SELECT
	'IF OBJECT_ID(''tempdb..#Subnet'') IS NULL' + CAST(0x0A AS CHAR(1)) +
	'	CREATE TABLE #Subnet (' + CAST(0x0A AS CHAR(1)) +
	'		SubnetID		int NULL,' + CAST(0x0A AS CHAR(1)) +
	'		IPSubnet		nvarchar(64) COLLATE database_default NOT NULL,' + CAST(0x0A AS CHAR(1)) +
	'		IPSubnetMask		nvarchar(64) COLLATE database_default NOT NULL,' + CAST(0x0A AS CHAR(1)) +
	'		NetworkLocationID	int NOT NULL,' + CAST(0x0A AS CHAR(1)) +
	'		AutoPopulated		bit NOT NULL DEFAULT 0,' + CAST(0x0A AS CHAR(1)) +
	'		Enabled			bit NOT NULL DEFAULT 1' + CAST(0x0A AS CHAR(1)) +
	'	)' + CAST(0x0A AS CHAR(1)) +
	'ELSE' + CAST(0x0A AS CHAR(1)) +
	'	DELETE FROM #Subnet' + CAST(0x0A AS CHAR(1)) +
	'' AS SQL
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[SubnetTempAdd]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[SubnetTempAdd]
GO
CREATE PROCEDURE dbo.[SubnetTempAdd]
	@SubnetID		int,
	@IPSubnet		nvarchar(64),
	@IPSubnetMask		nvarchar(64),
	@NetworkLocationID	int,
	@AutoPopulated		bit = 0,
	@Enabled		bit = 1
AS
	INSERT INTO #Subnet (
		SubnetID,
		IPSubnet,
		IPSubnetMask,
		NetworkLocationID,
		AutoPopulated,
		Enabled
	)
	VALUES (
		@SubnetID,
		@IPSubnet,
		@IPSubnetMask,
		@NetworkLocationID,
		@AutoPopulated,
		@Enabled
	)
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[SubnetAddBatch]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[SubnetAddBatch]
GO
CREATE PROCEDURE dbo.[SubnetAddBatch]
AS
	DECLARE @count int
	INSERT dbo.Subnet (
		IPSubnet,
		IPSubnetMask,
		NetworkLocationID,
		AutoPopulated,
		Enabled
	)
		SELECT	IPSubnet,
			IPSubnetMask,
			NetworkLocationID,
			AutoPopulated,
			Enabled
		FROM #Subnet
	SET @count = @@ROWCOUNT
	DROP TABLE #Subnet	-- Drop temporary table
	RETURN @count
GO

/*
Add new Subnet bound to
	NetworkLocation using DN with Name, DomainID
	with IPSubnet, IPSubnetMask, AutoPopulated, Enabled
*/

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[SubnetUpdateByID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[SubnetUpdateByID]
GO
CREATE PROCEDURE [dbo].[SubnetUpdateByID]
	@SubnetID		int,
	@IPSubnet		nvarchar(64),
	@IPSubnetMask		nvarchar(64),
	@NetworkLocationID	int,
	@AutoPopulated		bit = 0,
	@Enabled		bit = 1
AS
	DECLARE	@ID	int
	SET @ID = 0

	UPDATE	[dbo].[Subnet]
	SET	@ID = SubnetID,
		IPSubnet = @IPSubnet,
		IPSubnetMask = @IPSubnetMask,
		NetworkLocationID = @NetworkLocationID,
		AutoPopulated = @AutoPopulated,
		Enabled = @Enabled
	WHERE	SubnetID = @SubnetID
	RETURN @ID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[SubnetUpdateBatchByID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[SubnetUpdateBatchByID]
GO
CREATE PROCEDURE dbo.[SubnetUpdateBatchByID]
AS
	DECLARE @count int

	CREATE INDEX [TempSubnetID]
		ON #Subnet (SubnetID)

	UPDATE	[dbo].[Subnet]
	SET	IPSubnet = t.IPSubnet,
		IPSubnetMask = t.IPSubnetMask,
		NetworkLocationID = t.NetworkLocationID,
		AutoPopulated = t.AutoPopulated,
		Enabled = t.Enabled
	FROM	#Subnet AS t
	WHERE	Subnet.SubnetID = t.SubnetID
	SET @count = @@ROWCOUNT
	DROP TABLE #Subnet	-- Drop the temporary table
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[SubnetUpdateByIPSubnetIPSubnetMaskNetworkLocationID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[SubnetUpdateByIPSubnetIPSubnetMaskNetworkLocationID]
GO
CREATE PROCEDURE [dbo].[SubnetUpdateByIPSubnetIPSubnetMaskNetworkLocationID]
	@IPSubnet		nvarchar(64),
	@IPSubnetMask		nvarchar(64),
	@NetworkLocationID	int,
	@AutoPopulated		bit = 0,
	@Enabled		bit = 1
AS
	DECLARE	@ID	int
	SET @ID = 0

	UPDATE	[dbo].[Subnet]
	SET	@ID = SubnetID,
		AutoPopulated = @AutoPopulated,
		Enabled = @Enabled
	WHERE	IPSubnet = @IPSubnet
	  AND	IPSubnetMask = @IPSubnetMask
	  AND	NetworkLocationID = @NetworkLocationID
	RETURN @ID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[SubnetUpdateBatchByIPSubnetIPSubnetMaskNetworkLocationID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[SubnetUpdateBatchByIPSubnetIPSubnetMaskNetworkLocationID]
GO
CREATE PROCEDURE dbo.[SubnetUpdateBatchByIPSubnetIPSubnetMaskNetworkLocationID]
AS
	DECLARE @count int

	CREATE INDEX [TempSubnetIPSubnetIPSubnetMaskNetworkLocationID]
		ON #Subnet (IPSubnet, IPSubnetMask, NetworkLocationID)

	UPDATE	[dbo].[Subnet]
	SET	AutoPopulated = t.AutoPopulated,
		Enabled = t.Enabled
	FROM	#Subnet AS t
	WHERE	Subnet.IPSubnet = t.IPSubnet
	  AND	Subnet.IPSubnetMask = t.IPSubnetMask
	  AND	Subnet.NetworkLocationID = t.NetworkLocationID
	SET @count = @@ROWCOUNT
	DROP TABLE #Subnet	-- Drop the temporary table
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[SubnetPutByIPSubnetIPSubnetMaskNetworkLocationID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[SubnetPutByIPSubnetIPSubnetMaskNetworkLocationID]
GO
CREATE PROCEDURE [dbo].[SubnetPutByIPSubnetIPSubnetMaskNetworkLocationID]
	@IPSubnet		nvarchar(64),
	@IPSubnetMask		nvarchar(64),
	@NetworkLocationID	int,
	@AutoPopulated		bit = 0,
	@Enabled		bit = 1
AS
	DECLARE @ID	int

	SELECT	@ID = SubnetID
	FROM	Subnet
	WHERE	IPSubnet = @IPSubnet
	  AND	IPSubnetMask = @IPSubnetMask
	  AND	NetworkLocationID = @NetworkLocationID

	IF @ID IS NULL
		EXEC @ID = SubnetAdd @IPSubnet,
			@IPSubnetMask,
			@NetworkLocationID,
			@AutoPopulated,
			@Enabled
	ELSE
		EXEC SubnetUpdateByIPSubnetIPSubnetMaskNetworkLocationID @IPSubnet,
			@IPSubnetMask,
			@NetworkLocationID,
			@AutoPopulated,
			@Enabled

	RETURN @ID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[SubnetPutBatchByIPSubnetIPSubnetMaskNetworkLocationID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[SubnetPutBatchByIPSubnetIPSubnetMaskNetworkLocationID]
GO
CREATE PROCEDURE [dbo].[SubnetPutBatchByIPSubnetIPSubnetMaskNetworkLocationID]
AS
	DECLARE @count AS int
	SET @count = 0

	CREATE INDEX [TempSubnetIPSubnetIPSubnetMaskNetworkLocationID]
		ON #Subnet (IPSubnet, IPSubnetMask, NetworkLocationID)

	BEGIN TRANSACTION
	UPDATE [dbo].[Subnet]
		SET	AutoPopulated = t.AutoPopulated,
			Enabled = t.Enabled
		FROM	#Subnet AS t
		WHERE	Subnet.IPSubnet = t.IPSubnet
		  AND	Subnet.IPSubnetMask = t.IPSubnetMask
		  AND	Subnet.NetworkLocationID = t.NetworkLocationID
	SET @count = @@ROWCOUNT

	INSERT [dbo].[Subnet] (
		IPSubnet,
		IPSubnetMask,
		NetworkLocationID,
		AutoPopulated,
		Enabled
	)
		SELECT	IPSubnet,
			IPSubnetMask,
			NetworkLocationID,
			AutoPopulated,
			Enabled
		FROM	#Subnet AS t
		WHERE NOT EXISTS(	-- Current record doesn't exist
			SELECT * FROM [dbo].[Subnet]
			WHERE	Subnet.IPSubnet = t.IPSubnet
			  AND	Subnet.IPSubnetMask = t.IPSubnetMask
			  AND	Subnet.NetworkLocationID = t.NetworkLocationID
		)
	SET @count = @count + @@ROWCOUNT
	DROP TABLE #Subnet	-- Drop the temporary table
	COMMIT WORK
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[SubnetRemoveBatch]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[SubnetRemoveBatch]
GO

CREATE PROCEDURE [dbo].[SubnetRemoveBatch]
AS

	CREATE INDEX [TempSubnetSubnetRemoveBatch]
		ON #Subnet (SubnetID)	

	-- Delete records from Subnet identified by fields of [TempSubnetSubnetRemoveBatch]
	DELETE [dbo].[Subnet]
	WHERE EXISTS(
			SELECT * FROM #Subnet AS t
			WHERE	Subnet.SubnetID = t.SubnetID
		)
	DROP TABLE #Subnet      -- Drop the temporary table
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[SubnetRemoveByID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[SubnetRemoveByID]
GO
CREATE PROCEDURE [dbo].[SubnetRemoveByID]
	@SubnetID		int
AS
	DELETE	[dbo].[Subnet]
	WHERE	SubnetID = @SubnetID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[SubnetRemoveByIPSubnetIPSubnetMaskNetworkLocationID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[SubnetRemoveByIPSubnetIPSubnetMaskNetworkLocationID]
GO
CREATE PROCEDURE [dbo].[SubnetRemoveByIPSubnetIPSubnetMaskNetworkLocationID]
	@IPSubnet		nvarchar(64),
	@IPSubnetMask		nvarchar(64),
	@NetworkLocationID	int
AS
	DELETE	[dbo].[Subnet]
	WHERE	IPSubnet = @IPSubnet
	  AND	IPSubnetMask = @IPSubnetMask
	  AND	NetworkLocationID = @NetworkLocationID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[SubnetRemoveAllByIPSubnetIPSubnetMask]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[SubnetRemoveAllByIPSubnetIPSubnetMask]
GO
CREATE PROCEDURE [dbo].[SubnetRemoveAllByIPSubnetIPSubnetMask]
	@IPSubnet		nvarchar(64),
	@IPSubnetMask		nvarchar(64)
AS
	DELETE	[dbo].[Subnet]
	WHERE	IPSubnet = @IPSubnet
	  AND	IPSubnetMask = @IPSubnetMask
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[SubnetRemoveAllByIPSubnet]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[SubnetRemoveAllByIPSubnet]
GO
CREATE PROCEDURE [dbo].[SubnetRemoveAllByIPSubnet]
	@IPSubnet		nvarchar(64)
AS
	DELETE	[dbo].[Subnet]
	WHERE	IPSubnet = @IPSubnet
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[SubnetRemoveAllByNetworkLocationID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[SubnetRemoveAllByNetworkLocationID]
GO
CREATE PROCEDURE [dbo].[SubnetRemoveAllByNetworkLocationID]
	@NetworkLocationID	int
AS
	DELETE	[dbo].[Subnet]
	WHERE	NetworkLocationID = @NetworkLocationID
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[SubnetRemoveAll]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[SubnetRemoveAll]
GO
CREATE PROCEDURE [dbo].[SubnetRemoveAll]
	
AS
	DELETE	[dbo].[Subnet]
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[OrganizationGetByID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[OrganizationGetByID]
GO
CREATE PROCEDURE [dbo].[OrganizationGetByID]
	@OrganizationID		int
AS
	SELECT	OrganizationID,
		RDN,
		GUID,
		DomainID,
		RDNReverse,
		IsUnknown,
		IsDomain,
		BlockInheritance
	FROM	[dbo].[Organization]
	WHERE	OrganizationID = @OrganizationID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[OrganizationGetByDomainIDRDN]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[OrganizationGetByDomainIDRDN]
GO
CREATE PROCEDURE [dbo].[OrganizationGetByDomainIDRDN]
	@DomainID		int = 0,
	@RDN			nvarchar(400) = NULL
AS
	SELECT	OrganizationID,
		RDN,
		GUID,
		DomainID,
		RDNReverse,
		IsUnknown,
		IsDomain,
		BlockInheritance
	FROM	[dbo].[Organization]
	WHERE	DomainID = @DomainID
	  AND	(RDN = @RDN OR (RDN IS NULL AND @RDN IS NULL))
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[OrganizationGetAllByDomainID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[OrganizationGetAllByDomainID]
GO
CREATE PROCEDURE [dbo].[OrganizationGetAllByDomainID]
	@DomainID		int = 0
AS
	SELECT	OrganizationID,
		RDN,
		GUID,
		DomainID,
		RDNReverse,
		IsUnknown,
		IsDomain,
		BlockInheritance
	FROM	[dbo].[Organization]
	WHERE	DomainID = @DomainID
	ORDER BY RDN
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[OrganizationGetByDomainIDRDNReverse]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[OrganizationGetByDomainIDRDNReverse]
GO
CREATE PROCEDURE [dbo].[OrganizationGetByDomainIDRDNReverse]
	@DomainID		int = 0,
	@RDNReverse		nvarchar(400) = NULL
AS
	SELECT	OrganizationID,
		RDN,
		GUID,
		DomainID,
		RDNReverse,
		IsUnknown,
		IsDomain,
		BlockInheritance
	FROM	[dbo].[Organization]
	WHERE	DomainID = @DomainID
	  AND	(RDNReverse = @RDNReverse OR (RDNReverse IS NULL AND @RDNReverse IS NULL))
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[OrganizationGetAllByGUID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[OrganizationGetAllByGUID]
GO
CREATE PROCEDURE [dbo].[OrganizationGetAllByGUID]
	@GUID			binary(16) = NULL
AS
	SELECT	OrganizationID,
		RDN,
		GUID,
		DomainID,
		RDNReverse,
		IsUnknown,
		IsDomain,
		BlockInheritance
	FROM	[dbo].[Organization]
	WHERE	(GUID = @GUID OR (GUID IS NULL AND @GUID IS NULL))
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[OrganizationGetAll]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[OrganizationGetAll]
GO
CREATE PROCEDURE [dbo].[OrganizationGetAll]
AS
	SELECT	OrganizationID,
		RDN,
		GUID,
		DomainID,
		RDNReverse,
		IsUnknown,
		IsDomain,
		BlockInheritance
	FROM	[dbo].[Organization]
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[OrganizationAdd]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[OrganizationAdd]
GO
CREATE PROCEDURE [dbo].[OrganizationAdd]
	@RDN			nvarchar(400) = NULL,
	@GUID			binary(16) = NULL,
	@DomainID		int = 0,
	@BlockInheritance	bit = 0
AS
	INSERT INTO  dbo.Organization (
		RDN,
		GUID,
		DomainID,
		BlockInheritance
	)
	VALUES (
		@RDN,
		@GUID,
		@DomainID,
		@BlockInheritance
	)
	RETURN SCOPE_IDENTITY()
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[OrganizationBind]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[OrganizationBind]
GO
CREATE PROCEDURE [dbo].[OrganizationBind]
	@RDN			nvarchar(400) = NULL,
	@GUID			binary(16) = NULL,
	@DomainID		int = 0,
	@BlockInheritance	bit = 0
AS
	DECLARE	@ID	int

	SELECT	@ID = OrganizationID
	FROM	[dbo].[Organization]
	WHERE	DomainID = @DomainID
	  AND	(RDN = @RDN OR (RDN IS NULL AND @RDN IS NULL))

	IF @ID IS NULL
		EXEC @ID = OrganizationAdd @RDN,
			@GUID,
			@DomainID,
			@BlockInheritance

	RETURN @ID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[OrganizationSchema]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[OrganizationSchema]
GO
CREATE PROCEDURE [dbo].[OrganizationSchema]
AS
	SELECT
	'IF OBJECT_ID(''tempdb..#Organization'') IS NULL' + CAST(0x0A AS CHAR(1)) +
	'	CREATE TABLE #Organization (' + CAST(0x0A AS CHAR(1)) +
	'		OrganizationID		int NULL,' + CAST(0x0A AS CHAR(1)) +
	'		RDN			nvarchar(400) COLLATE database_default NULL,' + CAST(0x0A AS CHAR(1)) +
	'		GUID			binary(16) NULL,' + CAST(0x0A AS CHAR(1)) +
	'		DomainID		int NOT NULL DEFAULT 0,' + CAST(0x0A AS CHAR(1)) +
	'		BlockInheritance	bit NOT NULL DEFAULT 0' + CAST(0x0A AS CHAR(1)) +
	'	)' + CAST(0x0A AS CHAR(1)) +
	'ELSE' + CAST(0x0A AS CHAR(1)) +
	'	DELETE FROM #Organization' + CAST(0x0A AS CHAR(1)) +
	'' AS SQL
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[OrganizationTempAdd]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[OrganizationTempAdd]
GO
CREATE PROCEDURE dbo.[OrganizationTempAdd]
	@OrganizationID		int,
	@RDN			nvarchar(400) = NULL,
	@GUID			binary(16) = NULL,
	@DomainID		int = 0,
	@BlockInheritance	bit = 0
AS
	INSERT INTO #Organization (
		OrganizationID,
		RDN,
		GUID,
		DomainID,
		BlockInheritance
	)
	VALUES (
		@OrganizationID,
		@RDN,
		@GUID,
		@DomainID,
		@BlockInheritance
	)
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[OrganizationAddBatch]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[OrganizationAddBatch]
GO
CREATE PROCEDURE dbo.[OrganizationAddBatch]
AS
	DECLARE @count int
	INSERT dbo.Organization (
		RDN,
		GUID,
		DomainID,
		BlockInheritance
	)
		SELECT	RDN,
			GUID,
			DomainID,
			BlockInheritance
		FROM #Organization
	SET @count = @@ROWCOUNT
	DROP TABLE #Organization	-- Drop temporary table
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[OrganizationUpdateByID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[OrganizationUpdateByID]
GO
CREATE PROCEDURE [dbo].[OrganizationUpdateByID]
	@OrganizationID		int,
	@RDN			nvarchar(400) = NULL,
	@GUID			binary(16) = NULL,
	@DomainID		int = 0,
	@BlockInheritance	bit = 0
AS
	DECLARE	@ID	int
	SET @ID = 0

	UPDATE	[dbo].[Organization]
	SET	@ID = OrganizationID,
		RDN = @RDN,
		GUID = @GUID,
		DomainID = @DomainID,
		BlockInheritance = @BlockInheritance
	WHERE	OrganizationID = @OrganizationID
	RETURN @ID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[OrganizationUpdateBatchByID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[OrganizationUpdateBatchByID]
GO
CREATE PROCEDURE dbo.[OrganizationUpdateBatchByID]
AS
	DECLARE @count int

	CREATE INDEX [TempOrganizationID]
		ON #Organization (OrganizationID)

	UPDATE	[dbo].[Organization]
	SET	RDN = t.RDN,
		GUID = t.GUID,
		DomainID = t.DomainID,
		BlockInheritance = t.BlockInheritance
	FROM	#Organization AS t
	WHERE	Organization.OrganizationID = t.OrganizationID
	SET @count = @@ROWCOUNT
	DROP TABLE #Organization	-- Drop the temporary table
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[OrganizationUpdateByDomainIDRDN]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[OrganizationUpdateByDomainIDRDN]
GO
CREATE PROCEDURE [dbo].[OrganizationUpdateByDomainIDRDN]
	@DomainID		int = 0,
	@RDN			nvarchar(400) = NULL,
	@GUID			binary(16) = NULL,
	@BlockInheritance	bit = 0
AS
	DECLARE	@ID	int
	SET @ID = 0

	UPDATE	[dbo].[Organization]
	SET	@ID = OrganizationID,
		GUID = @GUID,
		BlockInheritance = @BlockInheritance
	WHERE	DomainID = @DomainID
	  AND	(RDN = @RDN OR (RDN IS NULL AND @RDN IS NULL))
	RETURN @ID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[OrganizationUpdateBatchByDomainIDRDN]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[OrganizationUpdateBatchByDomainIDRDN]
GO
CREATE PROCEDURE dbo.[OrganizationUpdateBatchByDomainIDRDN]
AS
	DECLARE @count int

	CREATE INDEX [TempOrganizationDomainIDRDN]
		ON #Organization (DomainID, RDN)

	UPDATE	[dbo].[Organization]
	SET	GUID = t.GUID,
		BlockInheritance = t.BlockInheritance
	FROM	#Organization AS t
	WHERE	Organization.DomainID = t.DomainID
	  AND	(Organization.RDN = t.RDN OR (Organization.RDN IS NULL AND t.RDN IS NULL))
	SET @count = @@ROWCOUNT
	DROP TABLE #Organization	-- Drop the temporary table
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[OrganizationPutByDomainIDRDN]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[OrganizationPutByDomainIDRDN]
GO
CREATE PROCEDURE [dbo].[OrganizationPutByDomainIDRDN]
	@DomainID		int = 0,
	@RDN			nvarchar(400) = NULL,
	@GUID			binary(16) = NULL,
	@BlockInheritance	bit = 0
AS
	DECLARE @ID	int

	SELECT	@ID = OrganizationID
	FROM	Organization
	WHERE	DomainID = @DomainID
	  AND	(RDN = @RDN OR (RDN IS NULL AND @RDN IS NULL))

	IF @ID IS NULL
		EXEC @ID = OrganizationAdd @RDN,
			@GUID,
			@DomainID,
			@BlockInheritance
	ELSE
		EXEC OrganizationUpdateByDomainIDRDN @DomainID,
			@RDN,
			@GUID,
			@BlockInheritance

	RETURN @ID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[OrganizationPutBatchByDomainIDRDN]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[OrganizationPutBatchByDomainIDRDN]
GO
CREATE PROCEDURE [dbo].[OrganizationPutBatchByDomainIDRDN]
AS
	DECLARE @count AS int
	SET @count = 0

	CREATE INDEX [TempOrganizationDomainIDRDN]
		ON #Organization (DomainID, RDN)

	BEGIN TRANSACTION
	UPDATE [dbo].[Organization]
		SET	GUID = t.GUID,
			BlockInheritance = t.BlockInheritance
		FROM	#Organization AS t
		WHERE	Organization.DomainID = t.DomainID
		  AND	(Organization.RDN = t.RDN OR (Organization.RDN IS NULL AND t.RDN IS NULL))
	SET @count = @@ROWCOUNT

	INSERT [dbo].[Organization] (
		RDN,
		GUID,
		DomainID,
		BlockInheritance
	)
		SELECT	RDN,
			GUID,
			DomainID,
			BlockInheritance
		FROM	#Organization AS t
		WHERE NOT EXISTS(	-- Current record doesn't exist
			SELECT * FROM [dbo].[Organization]
			WHERE	Organization.DomainID = t.DomainID
			  AND	(Organization.RDN = t.RDN OR (Organization.RDN IS NULL AND t.RDN IS NULL))
		)
	SET @count = @count + @@ROWCOUNT
	DROP TABLE #Organization	-- Drop the temporary table
	COMMIT WORK
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[OrganizationRemoveBatch]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[OrganizationRemoveBatch]
GO

CREATE PROCEDURE [dbo].[OrganizationRemoveBatch]
AS

	CREATE INDEX [TempOrganizationOrganizationRemoveBatch]
		ON #Organization (OrganizationID)	

	-- Delete records from Organization identified by fields of [TempOrganizationOrganizationRemoveBatch]
	DELETE [dbo].[Organization]
	WHERE EXISTS(
			SELECT * FROM #Organization AS t
			WHERE	Organization.OrganizationID = t.OrganizationID
		)
	DROP TABLE #Organization      -- Drop the temporary table
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[OrganizationRemoveByID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[OrganizationRemoveByID]
GO
CREATE PROCEDURE [dbo].[OrganizationRemoveByID]
	@OrganizationID		int
AS
	-- Organization deletes cascade to:
	--	Computer by FK_Computer_OU
	--		Installation by FK_Installation_Computer
	--		InstallationHistory by FK_InstallationHistory_Computer
	--		InventoryReport by FK_InventoryReport_Computer
	--		SoftwareOccurrence by FK_SoftwareOccurrence_Computer
	--			SoftwareValue by FK_SoftwareValue_SoftwareOccurrence
	--		SoftwareFile by FK_SoftwareFile_Computer
	--			SoftwareFileProperty by FK_SoftwareFileProperty_SoftwareFile
	--		HardwareObject by FK_HardwareObject_Computer
	--			HardwareValue by FK_HardwareValue_HardwareObject
	--		ServiceProvider by FK_ServiceProvider_Computer
	--			ServiceProviderValue by FK_ServiceProviderValue_ServiceProvider
	--			ServiceProviderComponent by FK_ServiceProviderComponent_ServiceProvider
	--			ServiceProviderComponentValue by FK_ServiceProviderComponentValue_ServiceProvider
	--			ServiceUser by FK_ServiceUser_ServiceProvider
	--				ServiceUserOracle by FK_ServiceUserOracle_ServiceUser
	--			ServiceProviderApplicationOracle by FK_ServiceProviderApplicationOracle_ServiceProvider
	--				ServiceProviderApplicationUserOracle by FK_ServiceProviderApplicationUserOracle_Application
	--		NetworkDevice by FK_NetworkDevice_Computer
	--			NetworkDeviceCalculatedMember by FK_NetworkDeviceCalculatedMember_NetworkDevice
	--			NetworkDeviceSNMPInfo by FK_NetworkDeviceSNMPInfo_NetworkDevice
	--			NetworkDeviceAMTInfo by FK_NetworkDeviceAMTInfo_NetworkDevice
	--			NetworkDeviceVirtualizationInfo by FK_NetworkDeviceVirtualizationInfo_NetworkDevice
	--			NetworkDeviceDiscoveredBy by FK_NetworkDeviceDiscoveredBy_Device
	--			KnownOracleListener by FK_KnownOracleListener_NetworkDevice
	--				KnownOracleService by FK_KnownOracleService_KnownOracleListener
	--			AgentStatus by FK_AgentStatus_NetworkDevice
	--			AMTEventLog by FK_AMTEventLog_NetworkDevice
	--		ActionApplies by FK_ActionApplies_Computer
	--		SoftwareUsagePerWeek by FK_SoftwareUsagePerWeek_Computer
	--		ComputerUsage by FK_ComputerUsage_Computer
	--		DeviceEvent by FK_DeviceEvent_Computer
	--		SessionStateEvent by FK_SessionStateEvent_Computer
	--		GeneralSecurityEvent by FK_GeneralSecurityEvent_Computer
	--		WakeOnLANStatus by FK_WOLStatus_Computer
	--	Group by FK_Group_Organization
	--		Member by FK_Member_Group
	--		TransitiveMember by FK_TransitiveMember_Group
	--		PackageAllocation by FK_Allocation_AccessGroup
	--		Right by FK_Right_Group
	--	LicenseAllocation by FK_LicenseAllocation_OrganizationID
	--	LicensePurchase by FK_LicensePurchase_Organization
	--	PolicyApplies by FK_PolicyApplies_OU
	--	PackageApplies by FK_PackageApplies_OU
	-- Organization deletes may fail due to non-cascading FKs:
	--	Domain by FK_Domain_ID
	--	User by FK_User_OU
	--	(through Computer by FK_Computer_OU)
	--		(through ServiceProvider by FK_ServiceProvider_Computer)
	--			ServiceProvider by FK_ServiceProvider_Parent
	--		(through NetworkDevice by FK_NetworkDevice_Computer)
	--			NetworkDevice by FK_NetworkDevice_Duplicate
	--			NetworkDeviceParent by FK_NetworkDeviceChild_NetworkDevice
	--			NetworkDeviceParent by FK_NetworkDeviceParent_NetworkDevice
	--			KnownOracleService by FK_KnownOracleService_NetworkDevice
	--			ActionApplies by FK_ActionApplies_DeviceID
	--	(through Group by FK_Group_Organization)
	--		Policy by FK_Policy_AccessGroup
	--	Installation by FK_Installation_Organization
	DELETE	[dbo].[Organization]
	WHERE	OrganizationID = @OrganizationID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[OrganizationRemoveByDomainIDRDN]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[OrganizationRemoveByDomainIDRDN]
GO
CREATE PROCEDURE [dbo].[OrganizationRemoveByDomainIDRDN]
	@DomainID		int = 0,
	@RDN			nvarchar(400) = NULL
AS
	-- Organization deletes cascade to:
	--	Computer by FK_Computer_OU
	--		Installation by FK_Installation_Computer
	--		InstallationHistory by FK_InstallationHistory_Computer
	--		InventoryReport by FK_InventoryReport_Computer
	--		SoftwareOccurrence by FK_SoftwareOccurrence_Computer
	--			SoftwareValue by FK_SoftwareValue_SoftwareOccurrence
	--		SoftwareFile by FK_SoftwareFile_Computer
	--			SoftwareFileProperty by FK_SoftwareFileProperty_SoftwareFile
	--		HardwareObject by FK_HardwareObject_Computer
	--			HardwareValue by FK_HardwareValue_HardwareObject
	--		ServiceProvider by FK_ServiceProvider_Computer
	--			ServiceProviderValue by FK_ServiceProviderValue_ServiceProvider
	--			ServiceProviderComponent by FK_ServiceProviderComponent_ServiceProvider
	--			ServiceProviderComponentValue by FK_ServiceProviderComponentValue_ServiceProvider
	--			ServiceUser by FK_ServiceUser_ServiceProvider
	--				ServiceUserOracle by FK_ServiceUserOracle_ServiceUser
	--			ServiceProviderApplicationOracle by FK_ServiceProviderApplicationOracle_ServiceProvider
	--				ServiceProviderApplicationUserOracle by FK_ServiceProviderApplicationUserOracle_Application
	--		NetworkDevice by FK_NetworkDevice_Computer
	--			NetworkDeviceCalculatedMember by FK_NetworkDeviceCalculatedMember_NetworkDevice
	--			NetworkDeviceSNMPInfo by FK_NetworkDeviceSNMPInfo_NetworkDevice
	--			NetworkDeviceAMTInfo by FK_NetworkDeviceAMTInfo_NetworkDevice
	--			NetworkDeviceVirtualizationInfo by FK_NetworkDeviceVirtualizationInfo_NetworkDevice
	--			NetworkDeviceDiscoveredBy by FK_NetworkDeviceDiscoveredBy_Device
	--			KnownOracleListener by FK_KnownOracleListener_NetworkDevice
	--				KnownOracleService by FK_KnownOracleService_KnownOracleListener
	--			AgentStatus by FK_AgentStatus_NetworkDevice
	--			AMTEventLog by FK_AMTEventLog_NetworkDevice
	--		ActionApplies by FK_ActionApplies_Computer
	--		SoftwareUsagePerWeek by FK_SoftwareUsagePerWeek_Computer
	--		ComputerUsage by FK_ComputerUsage_Computer
	--		DeviceEvent by FK_DeviceEvent_Computer
	--		SessionStateEvent by FK_SessionStateEvent_Computer
	--		GeneralSecurityEvent by FK_GeneralSecurityEvent_Computer
	--		WakeOnLANStatus by FK_WOLStatus_Computer
	--	Group by FK_Group_Organization
	--		Member by FK_Member_Group
	--		TransitiveMember by FK_TransitiveMember_Group
	--		PackageAllocation by FK_Allocation_AccessGroup
	--		Right by FK_Right_Group
	--	LicenseAllocation by FK_LicenseAllocation_OrganizationID
	--	LicensePurchase by FK_LicensePurchase_Organization
	--	PolicyApplies by FK_PolicyApplies_OU
	--	PackageApplies by FK_PackageApplies_OU
	-- Organization deletes may fail due to non-cascading FKs:
	--	Domain by FK_Domain_ID
	--	User by FK_User_OU
	--	(through Computer by FK_Computer_OU)
	--		(through ServiceProvider by FK_ServiceProvider_Computer)
	--			ServiceProvider by FK_ServiceProvider_Parent
	--		(through NetworkDevice by FK_NetworkDevice_Computer)
	--			NetworkDevice by FK_NetworkDevice_Duplicate
	--			NetworkDeviceParent by FK_NetworkDeviceChild_NetworkDevice
	--			NetworkDeviceParent by FK_NetworkDeviceParent_NetworkDevice
	--			KnownOracleService by FK_KnownOracleService_NetworkDevice
	--			ActionApplies by FK_ActionApplies_DeviceID
	--	(through Group by FK_Group_Organization)
	--		Policy by FK_Policy_AccessGroup
	--	Installation by FK_Installation_Organization
	DELETE	[dbo].[Organization]
	WHERE	DomainID = @DomainID
	  AND	(RDN = @RDN OR (RDN IS NULL AND @RDN IS NULL))
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[OrganizationRemoveAllByDomainID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[OrganizationRemoveAllByDomainID]
GO
CREATE PROCEDURE [dbo].[OrganizationRemoveAllByDomainID]
	@DomainID		int = 0
AS
	DELETE	[dbo].[Organization]
	WHERE	DomainID = @DomainID
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[OrganizationRemoveAllByGUID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[OrganizationRemoveAllByGUID]
GO
CREATE PROCEDURE [dbo].[OrganizationRemoveAllByGUID]
	@GUID			binary(16) = NULL
AS
	DELETE	[dbo].[Organization]
	WHERE	(GUID = @GUID OR (GUID IS NULL AND @GUID IS NULL))
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[OrganizationRemoveAll]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[OrganizationRemoveAll]
GO
CREATE PROCEDURE [dbo].[OrganizationRemoveAll]
	
AS
	DELETE	[dbo].[Organization]
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[OrganizationReplaceSubsetByDomainID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[OrganizationReplaceSubsetByDomainID]
GO
-- Replace the record subset selected by (@DomainID)
-- using unique identifier (DomainID, RDN)
-- updating fields (GUID, BlockInheritance)
CREATE PROCEDURE [dbo].[OrganizationReplaceSubsetByDomainID]
	@DomainID		int = 0
AS
	DECLARE @count AS int
	SET @count = 0

	CREATE INDEX [TempOrganizationByDomainID]
		ON #Organization (DomainID, RDN)

	BEGIN TRANSACTION
	DELETE [Organization]
		WHERE	DomainID = @DomainID
		AND NOT EXISTS(		-- Replacement record doesn't exist
			SELECT * FROM #Organization AS t
			WHERE	Organization.DomainID = t.DomainID
			  AND	(Organization.RDN = t.RDN OR (Organization.RDN IS NULL AND t.RDN IS NULL))
		)

	UPDATE [dbo].[Organization]
		SET	GUID = t.GUID,
			BlockInheritance = t.BlockInheritance
		FROM	#Organization AS t
		WHERE	Organization.DomainID = t.DomainID
		  AND	(Organization.RDN = t.RDN OR (Organization.RDN IS NULL AND t.RDN IS NULL))
	SET @count = @@ROWCOUNT

	INSERT [Organization] (
		RDN,
		GUID,
		DomainID,
		BlockInheritance
	)
		SELECT	RDN,
			GUID,
			DomainID,
			BlockInheritance
		FROM	#Organization AS t
		WHERE NOT EXISTS(	-- Current record doesn't exist
			SELECT * FROM [Organization]
			WHERE	Organization.DomainID = t.DomainID
			  AND	(Organization.RDN = t.RDN OR (Organization.RDN IS NULL AND t.RDN IS NULL))
		)
	SET @count = @count + @@ROWCOUNT
	DROP TABLE #Organization	-- Drop the temporary table
	COMMIT WORK
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[OrganizationReplaceSubsetByGUID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[OrganizationReplaceSubsetByGUID]
GO
-- Replace the record subset selected by (@GUID)
-- using unique identifier (DomainID, RDN)
-- updating fields (BlockInheritance)
CREATE PROCEDURE [dbo].[OrganizationReplaceSubsetByGUID]
	@GUID			binary(16) = NULL
AS
	DECLARE @count AS int
	SET @count = 0

	CREATE INDEX [TempOrganizationByGUID]
		ON #Organization (DomainID, RDN)

	BEGIN TRANSACTION
	DELETE [Organization]
		WHERE	(GUID = @GUID OR (GUID IS NULL AND @GUID IS NULL))
		AND NOT EXISTS(		-- Replacement record doesn't exist
			SELECT * FROM #Organization AS t
			WHERE	Organization.DomainID = t.DomainID
			  AND	(Organization.RDN = t.RDN OR (Organization.RDN IS NULL AND t.RDN IS NULL))
		)

	UPDATE [dbo].[Organization]
		SET	BlockInheritance = t.BlockInheritance
		FROM	#Organization AS t
		WHERE	Organization.DomainID = t.DomainID
		  AND	(Organization.RDN = t.RDN OR (Organization.RDN IS NULL AND t.RDN IS NULL))
	SET @count = @@ROWCOUNT

	INSERT [Organization] (
		RDN,
		GUID,
		DomainID,
		BlockInheritance
	)
		SELECT	RDN,
			GUID,
			DomainID,
			BlockInheritance
		FROM	#Organization AS t
		WHERE NOT EXISTS(	-- Current record doesn't exist
			SELECT * FROM [Organization]
			WHERE	Organization.DomainID = t.DomainID
			  AND	(Organization.RDN = t.RDN OR (Organization.RDN IS NULL AND t.RDN IS NULL))
		)
	SET @count = @count + @@ROWCOUNT
	DROP TABLE #Organization	-- Drop the temporary table
	COMMIT WORK
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[DomainGetByOrganizationID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[DomainGetByOrganizationID]
GO
CREATE PROCEDURE [dbo].[DomainGetByOrganizationID]
	@OrganizationID		int
AS
	SELECT	OrganizationID,
		DN,
		DomainType,
		FlatName,
		PreferredDomainController,
		PreferredDomainControllerOnly,
		ADReconcile,
		ADLoadLatency,
		MergePolicies,
		LastADReconcile,
		LastADReconcileStatus,
		LastADLoad,
		LastPolicyMerge,
		LastPolicyMergeStatus,
		DNReverse
	FROM	[dbo].[Domain]
	WHERE	OrganizationID = @OrganizationID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[DomainGetByDN]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[DomainGetByDN]
GO
CREATE PROCEDURE [dbo].[DomainGetByDN]
	@DN			nvarchar(100) = NULL
AS
	SELECT	OrganizationID,
		DN,
		DomainType,
		FlatName,
		PreferredDomainController,
		PreferredDomainControllerOnly,
		ADReconcile,
		ADLoadLatency,
		MergePolicies,
		LastADReconcile,
		LastADReconcileStatus,
		LastADLoad,
		LastPolicyMerge,
		LastPolicyMergeStatus,
		DNReverse
	FROM	[dbo].[Domain]
	WHERE	(DN = @DN OR (DN IS NULL AND @DN IS NULL))
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[DomainGetByDNReverse]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[DomainGetByDNReverse]
GO
CREATE PROCEDURE [dbo].[DomainGetByDNReverse]
	@DNReverse		nvarchar(100) = NULL
AS
	SELECT	OrganizationID,
		DN,
		DomainType,
		FlatName,
		PreferredDomainController,
		PreferredDomainControllerOnly,
		ADReconcile,
		ADLoadLatency,
		MergePolicies,
		LastADReconcile,
		LastADReconcileStatus,
		LastADLoad,
		LastPolicyMerge,
		LastPolicyMergeStatus,
		DNReverse
	FROM	[dbo].[Domain]
	WHERE	(DNReverse = @DNReverse OR (DNReverse IS NULL AND @DNReverse IS NULL))
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[DomainGetAllByType]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[DomainGetAllByType]
GO
CREATE PROCEDURE [dbo].[DomainGetAllByType]
	@DomainType		varchar(4) = NULL
AS
	SELECT	OrganizationID,
		DN,
		DomainType,
		FlatName,
		PreferredDomainController,
		PreferredDomainControllerOnly,
		ADReconcile,
		ADLoadLatency,
		MergePolicies,
		LastADReconcile,
		LastADReconcileStatus,
		LastADLoad,
		LastPolicyMerge,
		LastPolicyMergeStatus,
		DNReverse
	FROM	[dbo].[Domain]
	WHERE	(DomainType = @DomainType OR (DomainType IS NULL AND @DomainType IS NULL))
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[DomainGetAll]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[DomainGetAll]
GO
CREATE PROCEDURE [dbo].[DomainGetAll]
AS
	SELECT	OrganizationID,
		DN,
		DomainType,
		FlatName,
		PreferredDomainController,
		PreferredDomainControllerOnly,
		ADReconcile,
		ADLoadLatency,
		MergePolicies,
		LastADReconcile,
		LastADReconcileStatus,
		LastADLoad,
		LastPolicyMerge,
		LastPolicyMergeStatus,
		DNReverse
	FROM	[dbo].[Domain]
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[DomainConfigurationGetByDomainIDProperty]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[DomainConfigurationGetByDomainIDProperty]
GO
CREATE PROCEDURE [dbo].[DomainConfigurationGetByDomainIDProperty]
	@DomainID		int = 0,
	@Property		varchar(32)
AS
	SELECT	DomainID,
		Property,
		Value,
		DateValue,
		LastUpdate
	FROM	[dbo].[DomainConfiguration]
	WHERE	DomainID = @DomainID
	  AND	Property = @Property
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[DomainConfigurationGetAllByDomainID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[DomainConfigurationGetAllByDomainID]
GO
CREATE PROCEDURE [dbo].[DomainConfigurationGetAllByDomainID]
	@DomainID		int = 0
AS
	SELECT	DomainID,
		Property,
		Value,
		DateValue,
		LastUpdate
	FROM	[dbo].[DomainConfiguration]
	WHERE	DomainID = @DomainID
	ORDER BY Property
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[DomainConfigurationGetAll]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[DomainConfigurationGetAll]
GO
CREATE PROCEDURE [dbo].[DomainConfigurationGetAll]
AS
	SELECT	DomainID,
		Property,
		Value,
		DateValue,
		LastUpdate
	FROM	[dbo].[DomainConfiguration]
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[DomainConfigurationAdd]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[DomainConfigurationAdd]
GO
CREATE PROCEDURE [dbo].[DomainConfigurationAdd]
	@DomainID		int = 0,
	@Property		varchar(32),
	@Value			varchar(256) = NULL,
	@DateValue		datetime = NULL,
	@LastUpdate		datetime
AS
	INSERT INTO  dbo.DomainConfiguration (
		DomainID,
		Property,
		Value,
		DateValue,
		LastUpdate
	)
	VALUES (
		@DomainID,
		@Property,
		@Value,
		@DateValue,
		@LastUpdate
	)
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[DomainConfigurationSchema]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[DomainConfigurationSchema]
GO
CREATE PROCEDURE [dbo].[DomainConfigurationSchema]
AS
	SELECT
	'IF OBJECT_ID(''tempdb..#DomainConfiguration'') IS NULL' + CAST(0x0A AS CHAR(1)) +
	'	CREATE TABLE #DomainConfiguration (' + CAST(0x0A AS CHAR(1)) +
	'		DomainID		int NOT NULL DEFAULT 0,' + CAST(0x0A AS CHAR(1)) +
	'		Property		varchar(32) COLLATE database_default NOT NULL,' + CAST(0x0A AS CHAR(1)) +
	'		Value			varchar(256) COLLATE database_default NULL,' + CAST(0x0A AS CHAR(1)) +
	'		DateValue		datetime NULL,' + CAST(0x0A AS CHAR(1)) +
	'		LastUpdate		datetime NOT NULL DEFAULT getdate()' + CAST(0x0A AS CHAR(1)) +
	'	)' + CAST(0x0A AS CHAR(1)) +
	'ELSE' + CAST(0x0A AS CHAR(1)) +
	'	DELETE FROM #DomainConfiguration' + CAST(0x0A AS CHAR(1)) +
	'' AS SQL
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[DomainConfigurationTempAdd]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[DomainConfigurationTempAdd]
GO
CREATE PROCEDURE dbo.[DomainConfigurationTempAdd]
	@DomainID		int = 0,
	@Property		varchar(32),
	@Value			varchar(256) = NULL,
	@DateValue		datetime = NULL,
	@LastUpdate		datetime
AS
	INSERT INTO #DomainConfiguration (
		DomainID,
		Property,
		Value,
		DateValue,
		LastUpdate
	)
	VALUES (
		@DomainID,
		@Property,
		@Value,
		@DateValue,
		@LastUpdate
	)
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[DomainConfigurationAddBatch]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[DomainConfigurationAddBatch]
GO
CREATE PROCEDURE dbo.[DomainConfigurationAddBatch]
AS
	DECLARE @count int
	INSERT dbo.DomainConfiguration (
		DomainID,
		Property,
		Value,
		DateValue,
		LastUpdate
	)
		SELECT	DomainID,
			Property,
			Value,
			DateValue,
			LastUpdate
		FROM #DomainConfiguration
	SET @count = @@ROWCOUNT
	DROP TABLE #DomainConfiguration	-- Drop temporary table
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[DomainConfigurationUpdateByDomainIDProperty]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[DomainConfigurationUpdateByDomainIDProperty]
GO
CREATE PROCEDURE [dbo].[DomainConfigurationUpdateByDomainIDProperty]
	@DomainID		int = 0,
	@Property		varchar(32),
	@Value			varchar(256) = NULL,
	@DateValue		datetime = NULL,
	@LastUpdate		datetime
AS
	UPDATE	[dbo].[DomainConfiguration]
	SET	Value = @Value,
		DateValue = @DateValue,
		LastUpdate = @LastUpdate
	WHERE	DomainID = @DomainID
	  AND	Property = @Property
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[DomainConfigurationUpdateBatchByDomainIDProperty]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[DomainConfigurationUpdateBatchByDomainIDProperty]
GO
CREATE PROCEDURE dbo.[DomainConfigurationUpdateBatchByDomainIDProperty]
AS
	DECLARE @count int

	CREATE INDEX [TempDomainConfigurationDomainIDProperty]
		ON #DomainConfiguration (DomainID, Property)

	UPDATE	[dbo].[DomainConfiguration]
	SET	Value = t.Value,
		DateValue = t.DateValue,
		LastUpdate = t.LastUpdate
	FROM	#DomainConfiguration AS t
	WHERE	DomainConfiguration.DomainID = t.DomainID
	  AND	DomainConfiguration.Property = t.Property
	SET @count = @@ROWCOUNT
	DROP TABLE #DomainConfiguration	-- Drop the temporary table
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[DomainConfigurationPutByDomainIDProperty]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[DomainConfigurationPutByDomainIDProperty]
GO
CREATE PROCEDURE [dbo].[DomainConfigurationPutByDomainIDProperty]
	@DomainID		int = 0,
	@Property		varchar(32),
	@Value			varchar(256) = NULL,
	@DateValue		datetime = NULL,
	@LastUpdate		datetime
AS
	IF NOT EXISTS(
		SELECT	1
		FROM	dbo.DomainConfiguration
		WHERE	DomainID = @DomainID
		  AND	Property = @Property
	)
		EXEC DomainConfigurationAdd @DomainID,
			@Property,
			@Value,
			@DateValue,
			@LastUpdate
	ELSE
		EXEC DomainConfigurationUpdateByDomainIDProperty @DomainID,
			@Property,
			@Value,
			@DateValue,
			@LastUpdate
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[DomainConfigurationPutBatchByDomainIDProperty]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[DomainConfigurationPutBatchByDomainIDProperty]
GO
CREATE PROCEDURE [dbo].[DomainConfigurationPutBatchByDomainIDProperty]
AS
	DECLARE @count AS int
	SET @count = 0

	CREATE INDEX [TempDomainConfigurationDomainIDProperty]
		ON #DomainConfiguration (DomainID, Property)

	BEGIN TRANSACTION
	UPDATE [dbo].[DomainConfiguration]
		SET	Value = t.Value,
			DateValue = t.DateValue,
			LastUpdate = t.LastUpdate
		FROM	#DomainConfiguration AS t
		WHERE	DomainConfiguration.DomainID = t.DomainID
		  AND	DomainConfiguration.Property = t.Property
	SET @count = @@ROWCOUNT

	INSERT [dbo].[DomainConfiguration] (
		DomainID,
		Property,
		Value,
		DateValue,
		LastUpdate
	)
		SELECT	DomainID,
			Property,
			Value,
			DateValue,
			LastUpdate
		FROM	#DomainConfiguration AS t
		WHERE NOT EXISTS(	-- Current record doesn't exist
			SELECT * FROM [dbo].[DomainConfiguration]
			WHERE	DomainConfiguration.DomainID = t.DomainID
			  AND	DomainConfiguration.Property = t.Property
		)
	SET @count = @count + @@ROWCOUNT
	DROP TABLE #DomainConfiguration	-- Drop the temporary table
	COMMIT WORK
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[DomainConfigurationRemoveBatch]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[DomainConfigurationRemoveBatch]
GO

CREATE PROCEDURE [dbo].[DomainConfigurationRemoveBatch]
AS

	CREATE INDEX [TempDomainConfigurationDomainConfigurationRemoveBatch]
		ON #DomainConfiguration (DomainID, Property)	

	-- Delete records from DomainConfiguration identified by fields of [TempDomainConfigurationDomainConfigurationRemoveBatch]
	DELETE [dbo].[DomainConfiguration]
	WHERE EXISTS(
			SELECT * FROM #DomainConfiguration AS t
			WHERE	DomainConfiguration.DomainID = t.DomainID
			  AND	DomainConfiguration.Property = t.Property
		)
	DROP TABLE #DomainConfiguration      -- Drop the temporary table
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[DomainConfigurationRemoveByDomainIDProperty]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[DomainConfigurationRemoveByDomainIDProperty]
GO
CREATE PROCEDURE [dbo].[DomainConfigurationRemoveByDomainIDProperty]
	@DomainID		int = 0,
	@Property		varchar(32)
AS
	DELETE	[dbo].[DomainConfiguration]
	WHERE	DomainID = @DomainID
	  AND	Property = @Property
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[DomainConfigurationRemoveAll]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[DomainConfigurationRemoveAll]
GO
CREATE PROCEDURE [dbo].[DomainConfigurationRemoveAll]
	
AS
	DELETE	[dbo].[DomainConfiguration]
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[UserGetByID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[UserGetByID]
GO
CREATE PROCEDURE [dbo].[UserGetByID]
	@UserID			int
AS
	SELECT	UserID,
		UserOUID,
		UserCN,
		GUID,
		SAMAccountName
	FROM	[dbo].[User]
	WHERE	UserID = @UserID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[UserGetByOUIDCN]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[UserGetByOUIDCN]
GO
CREATE PROCEDURE [dbo].[UserGetByOUIDCN]
	@UserOUID		int,
	@UserCN			nvarchar(64)
AS
	SELECT	UserID,
		UserOUID,
		UserCN,
		GUID,
		SAMAccountName
	FROM	[dbo].[User]
	WHERE	UserOUID = @UserOUID
	  AND	UserCN = @UserCN
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[UserGetByOUIDSAMAccountName]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[UserGetByOUIDSAMAccountName]
GO
CREATE PROCEDURE [dbo].[UserGetByOUIDSAMAccountName]
	@UserOUID		int,
	@SAMAccountName		nvarchar(20) = NULL
AS
	SELECT	UserID,
		UserOUID,
		UserCN,
		GUID,
		SAMAccountName
	FROM	[dbo].[User]
	WHERE	UserOUID = @UserOUID
	  AND	(SAMAccountName = @SAMAccountName OR (SAMAccountName IS NULL AND @SAMAccountName IS NULL))
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[UserGetAll]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[UserGetAll]
GO
CREATE PROCEDURE [dbo].[UserGetAll]
AS
	SELECT	UserID,
		UserOUID,
		UserCN,
		GUID,
		SAMAccountName
	FROM	[dbo].[User]
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[UserAdd]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[UserAdd]
GO
CREATE PROCEDURE [dbo].[UserAdd]
	@UserOUID		int,
	@UserCN			nvarchar(64),
	@GUID			binary(16) = NULL,
	@SAMAccountName		nvarchar(20) = NULL
AS
	INSERT INTO  dbo.[User] (
		UserOUID,
		UserCN,
		GUID,
		SAMAccountName
	)
	VALUES (
		@UserOUID,
		@UserCN,
		@GUID,
		@SAMAccountName
	)
	RETURN SCOPE_IDENTITY()
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[UserBind]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[UserBind]
GO
CREATE PROCEDURE [dbo].[UserBind]
	@UserOUID		int,
	@UserCN			nvarchar(64),
	@GUID			binary(16) = NULL,
	@SAMAccountName		nvarchar(20) = NULL
AS
	DECLARE	@ID	int

	SELECT	@ID = UserID
	FROM	[dbo].[User]
	WHERE	UserOUID = @UserOUID
	  AND	UserCN = @UserCN

	IF @ID IS NULL
		EXEC @ID = UserAdd @UserOUID,
			@UserCN,
			@GUID,
			@SAMAccountName

	RETURN @ID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[UserSchema]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[UserSchema]
GO
CREATE PROCEDURE [dbo].[UserSchema]
AS
	SELECT
	'IF OBJECT_ID(''tempdb..#User'') IS NULL' + CAST(0x0A AS CHAR(1)) +
	'	CREATE TABLE #User (' + CAST(0x0A AS CHAR(1)) +
	'		UserID			int NULL,' + CAST(0x0A AS CHAR(1)) +
	'		UserOUID		int NOT NULL,' + CAST(0x0A AS CHAR(1)) +
	'		UserCN			nvarchar(64) COLLATE database_default NOT NULL,' + CAST(0x0A AS CHAR(1)) +
	'		GUID			binary(16) NULL,' + CAST(0x0A AS CHAR(1)) +
	'		SAMAccountName		nvarchar(20) COLLATE database_default NULL' + CAST(0x0A AS CHAR(1)) +
	'	)' + CAST(0x0A AS CHAR(1)) +
	'ELSE' + CAST(0x0A AS CHAR(1)) +
	'	DELETE FROM #User' + CAST(0x0A AS CHAR(1)) +
	'' AS SQL
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[UserTempAdd]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[UserTempAdd]
GO
CREATE PROCEDURE dbo.[UserTempAdd]
	@UserID			int,
	@UserOUID		int,
	@UserCN			nvarchar(64),
	@GUID			binary(16) = NULL,
	@SAMAccountName		nvarchar(20) = NULL
AS
	INSERT INTO #User (
		UserID,
		UserOUID,
		UserCN,
		GUID,
		SAMAccountName
	)
	VALUES (
		@UserID,
		@UserOUID,
		@UserCN,
		@GUID,
		@SAMAccountName
	)
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[UserAddBatch]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[UserAddBatch]
GO
CREATE PROCEDURE dbo.[UserAddBatch]
AS
	DECLARE @count int
	INSERT dbo.[User] (
		UserOUID,
		UserCN,
		GUID,
		SAMAccountName
	)
		SELECT	UserOUID,
			UserCN,
			GUID,
			SAMAccountName
		FROM #User
	SET @count = @@ROWCOUNT
	DROP TABLE #User	-- Drop temporary table
	RETURN @count
GO

/*
Add new User bound to
	Organization using DomainID, RDN
	with UserCN, GUID, SAMAccountName
*/

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[UserUpdateByID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[UserUpdateByID]
GO
CREATE PROCEDURE [dbo].[UserUpdateByID]
	@UserID			int,
	@UserOUID		int,
	@UserCN			nvarchar(64),
	@GUID			binary(16) = NULL,
	@SAMAccountName		nvarchar(20) = NULL
AS
	DECLARE	@ID	int
	SET @ID = 0

	UPDATE	[dbo].[User]
	SET	@ID = UserID,
		UserOUID = @UserOUID,
		UserCN = @UserCN,
		GUID = @GUID,
		SAMAccountName = @SAMAccountName
	WHERE	UserID = @UserID
	RETURN @ID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[UserUpdateBatchByID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[UserUpdateBatchByID]
GO
CREATE PROCEDURE dbo.[UserUpdateBatchByID]
AS
	DECLARE @count int

	CREATE INDEX [TempUserID]
		ON #User (UserID)

	UPDATE	[dbo].[User]
	SET	UserOUID = t.UserOUID,
		UserCN = t.UserCN,
		GUID = t.GUID,
		SAMAccountName = t.SAMAccountName
	FROM	#User AS t
	WHERE	[User].UserID = t.UserID
	SET @count = @@ROWCOUNT
	DROP TABLE #User	-- Drop the temporary table
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[UserUpdateByOUIDCN]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[UserUpdateByOUIDCN]
GO
CREATE PROCEDURE [dbo].[UserUpdateByOUIDCN]
	@UserOUID		int,
	@UserCN			nvarchar(64),
	@GUID			binary(16) = NULL,
	@SAMAccountName		nvarchar(20) = NULL
AS
	DECLARE	@ID	int
	SET @ID = 0

	UPDATE	[dbo].[User]
	SET	@ID = UserID,
		GUID = @GUID,
		SAMAccountName = @SAMAccountName
	WHERE	UserOUID = @UserOUID
	  AND	UserCN = @UserCN
	RETURN @ID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[UserUpdateBatchByOUIDCN]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[UserUpdateBatchByOUIDCN]
GO
CREATE PROCEDURE dbo.[UserUpdateBatchByOUIDCN]
AS
	DECLARE @count int

	CREATE INDEX [TempUserOUIDCN]
		ON #User (UserOUID, UserCN)

	UPDATE	[dbo].[User]
	SET	GUID = t.GUID,
		SAMAccountName = t.SAMAccountName
	FROM	#User AS t
	WHERE	[User].UserOUID = t.UserOUID
	  AND	[User].UserCN = t.UserCN
	SET @count = @@ROWCOUNT
	DROP TABLE #User	-- Drop the temporary table
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[UserPutByOUIDCN]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[UserPutByOUIDCN]
GO
CREATE PROCEDURE [dbo].[UserPutByOUIDCN]
	@UserOUID		int,
	@UserCN			nvarchar(64),
	@GUID			binary(16) = NULL,
	@SAMAccountName		nvarchar(20) = NULL
AS
	DECLARE @ID	int

	SELECT	@ID = UserID
	FROM	[User]
	WHERE	UserOUID = @UserOUID
	  AND	UserCN = @UserCN

	IF @ID IS NULL
		EXEC @ID = UserAdd @UserOUID,
			@UserCN,
			@GUID,
			@SAMAccountName
	ELSE
		EXEC UserUpdateByOUIDCN @UserOUID,
			@UserCN,
			@GUID,
			@SAMAccountName

	RETURN @ID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[UserPutBatchByOUIDCN]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[UserPutBatchByOUIDCN]
GO
CREATE PROCEDURE [dbo].[UserPutBatchByOUIDCN]
AS
	DECLARE @count AS int
	SET @count = 0

	CREATE INDEX [TempUserOUIDCN]
		ON #User (UserOUID, UserCN)

	BEGIN TRANSACTION
	UPDATE [dbo].[User]
		SET	GUID = t.GUID,
			SAMAccountName = t.SAMAccountName
		FROM	#User AS t
		WHERE	[User].UserOUID = t.UserOUID
		  AND	[User].UserCN = t.UserCN
	SET @count = @@ROWCOUNT

	INSERT [dbo].[User] (
		UserOUID,
		UserCN,
		GUID,
		SAMAccountName
	)
		SELECT	UserOUID,
			UserCN,
			GUID,
			SAMAccountName
		FROM	#User AS t
		WHERE NOT EXISTS(	-- Current record doesn't exist
			SELECT * FROM [dbo].[User]
			WHERE	[User].UserOUID = t.UserOUID
			  AND	[User].UserCN = t.UserCN
		)
	SET @count = @count + @@ROWCOUNT
	DROP TABLE #User	-- Drop the temporary table
	COMMIT WORK
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[UserRemoveBatch]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[UserRemoveBatch]
GO

CREATE PROCEDURE [dbo].[UserRemoveBatch]
AS

	CREATE INDEX [TempUserUserRemoveBatch]
		ON #User (UserID)	

	-- Delete records from User identified by fields of [TempUserUserRemoveBatch]
	DELETE [dbo].[User]
	WHERE EXISTS(
			SELECT * FROM #User AS t
			WHERE	[User].UserID = t.UserID
		)
	DROP TABLE #User      -- Drop the temporary table
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[UserRemoveByOUIDCN]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[UserRemoveByOUIDCN]
GO
CREATE PROCEDURE [dbo].[UserRemoveByOUIDCN]
	@UserOUID		int,
	@UserCN			nvarchar(64)
AS
	-- User deletes cascade to:
	--	Installation by FK_Installation_User
	--	InstallationHistory by FK_InstallationHistory_User
	--	InventoryReport by FK_InventoryReport_User
	--	SoftwareOccurrence by FK_SoftwareOccurrence_User
	--		SoftwareValue by FK_SoftwareValue_SoftwareOccurrence
	--	SoftwareUsagePerWeek by FK_SoftwareUsagePerWeek_User
	--	ComputerUsage by FK_ComputerUsage_User
	--	SessionStateEvent by FK_SessionStateEvent_User
	--	GeneralSecurityEvent by FK_GeneralSecurityEvent_User
	DELETE	[dbo].[User]
	WHERE	UserOUID = @UserOUID
	  AND	UserCN = @UserCN
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[UserRemoveAll]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[UserRemoveAll]
GO
CREATE PROCEDURE [dbo].[UserRemoveAll]
	
AS
	DELETE	[dbo].[User]
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ComputerGetByID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ComputerGetByID]
GO
CREATE PROCEDURE [dbo].[ComputerGetByID]
	@ComputerID		int
AS
	SELECT	ComputerID,
		ComputerOUID,
		ComputerCN,
		OperatingSystemID,
		GUID
	FROM	[dbo].[Computer]
	WHERE	ComputerID = @ComputerID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ComputerGetAllByOUID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ComputerGetAllByOUID]
GO
CREATE PROCEDURE [dbo].[ComputerGetAllByOUID]
	@ComputerOUID		int
AS
	SELECT	ComputerID,
		ComputerOUID,
		ComputerCN,
		OperatingSystemID,
		GUID
	FROM	[dbo].[Computer]
	WHERE	ComputerOUID = @ComputerOUID
	ORDER BY ComputerCN
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ComputerGetAllByGUID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ComputerGetAllByGUID]
GO
CREATE PROCEDURE [dbo].[ComputerGetAllByGUID]
	@GUID			binary(16) = NULL
AS
	SELECT	ComputerID,
		ComputerOUID,
		ComputerCN,
		OperatingSystemID,
		GUID
	FROM	[dbo].[Computer]
	WHERE	(GUID = @GUID OR (GUID IS NULL AND @GUID IS NULL))
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ComputerGetAllByCN]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ComputerGetAllByCN]
GO
CREATE PROCEDURE [dbo].[ComputerGetAllByCN]
	@ComputerCN		nvarchar(64)
AS
	SELECT	ComputerID,
		ComputerOUID,
		ComputerCN,
		OperatingSystemID,
		GUID
	FROM	[dbo].[Computer]
	WHERE	ComputerCN = @ComputerCN
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ComputerGetAll]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ComputerGetAll]
GO
CREATE PROCEDURE [dbo].[ComputerGetAll]
AS
	SELECT	ComputerID,
		ComputerOUID,
		ComputerCN,
		OperatingSystemID,
		GUID
	FROM	[dbo].[Computer]
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ComputerAdd]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ComputerAdd]
GO
CREATE PROCEDURE [dbo].[ComputerAdd]
	@ComputerOUID		int,
	@ComputerCN		nvarchar(64),
	@OperatingSystemID	int = NULL,
	@GUID			binary(16) = NULL
AS
	INSERT INTO  dbo.Computer (
		ComputerOUID,
		ComputerCN,
		OperatingSystemID,
		GUID
	)
	VALUES (
		@ComputerOUID,
		@ComputerCN,
		@OperatingSystemID,
		@GUID
	)
	RETURN SCOPE_IDENTITY()
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ComputerBind]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ComputerBind]
GO
CREATE PROCEDURE [dbo].[ComputerBind]
	@ComputerOUID		int,
	@ComputerCN		nvarchar(64),
	@OperatingSystemID	int = NULL,
	@GUID			binary(16) = NULL
AS
	DECLARE	@ID	int

	SELECT	@ID = ComputerID
	FROM	[dbo].[Computer]
	WHERE	ComputerOUID = @ComputerOUID
	  AND	ComputerCN = @ComputerCN

	IF @ID IS NULL
		EXEC @ID = ComputerAdd @ComputerOUID,
			@ComputerCN,
			@OperatingSystemID,
			@GUID

	RETURN @ID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ComputerSchema]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ComputerSchema]
GO
CREATE PROCEDURE [dbo].[ComputerSchema]
AS
	SELECT
	'IF OBJECT_ID(''tempdb..#Computer'') IS NULL' + CAST(0x0A AS CHAR(1)) +
	'	CREATE TABLE #Computer (' + CAST(0x0A AS CHAR(1)) +
	'		ComputerID		int NULL,' + CAST(0x0A AS CHAR(1)) +
	'		ComputerOUID		int NOT NULL,' + CAST(0x0A AS CHAR(1)) +
	'		ComputerCN		nvarchar(64) COLLATE database_default NOT NULL,' + CAST(0x0A AS CHAR(1)) +
	'		OperatingSystemID	int NULL,' + CAST(0x0A AS CHAR(1)) +
	'		GUID			binary(16) NULL' + CAST(0x0A AS CHAR(1)) +
	'	)' + CAST(0x0A AS CHAR(1)) +
	'ELSE' + CAST(0x0A AS CHAR(1)) +
	'	DELETE FROM #Computer' + CAST(0x0A AS CHAR(1)) +
	'' AS SQL
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ComputerTempAdd]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ComputerTempAdd]
GO
CREATE PROCEDURE dbo.[ComputerTempAdd]
	@ComputerID		int,
	@ComputerOUID		int,
	@ComputerCN		nvarchar(64),
	@OperatingSystemID	int = NULL,
	@GUID			binary(16) = NULL
AS
	INSERT INTO #Computer (
		ComputerID,
		ComputerOUID,
		ComputerCN,
		OperatingSystemID,
		GUID
	)
	VALUES (
		@ComputerID,
		@ComputerOUID,
		@ComputerCN,
		@OperatingSystemID,
		@GUID
	)
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ComputerAddBatch]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ComputerAddBatch]
GO
CREATE PROCEDURE dbo.[ComputerAddBatch]
AS
	DECLARE @count int
	INSERT dbo.Computer (
		ComputerOUID,
		ComputerCN,
		OperatingSystemID,
		GUID
	)
		SELECT	ComputerOUID,
			ComputerCN,
			OperatingSystemID,
			GUID
		FROM #Computer
	SET @count = @@ROWCOUNT
	DROP TABLE #Computer	-- Drop temporary table
	RETURN @count
GO

/*
Add new Computer bound to
	Organization using DomainID, RDN
	with ComputerCN, OperatingSystemID, GUID
*/

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ComputerUpdateByID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ComputerUpdateByID]
GO
CREATE PROCEDURE [dbo].[ComputerUpdateByID]
	@ComputerID		int,
	@ComputerOUID		int,
	@ComputerCN		nvarchar(64),
	@OperatingSystemID	int = NULL,
	@GUID			binary(16) = NULL
AS
	DECLARE	@ID	int
	SET @ID = 0

	UPDATE	[dbo].[Computer]
	SET	@ID = ComputerID,
		ComputerOUID = @ComputerOUID,
		ComputerCN = @ComputerCN,
		OperatingSystemID = @OperatingSystemID,
		GUID = @GUID
	WHERE	ComputerID = @ComputerID
	RETURN @ID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ComputerUpdateBatchByID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ComputerUpdateBatchByID]
GO
CREATE PROCEDURE dbo.[ComputerUpdateBatchByID]
AS
	DECLARE @count int

	CREATE INDEX [TempComputerID]
		ON #Computer (ComputerID)

	UPDATE	[dbo].[Computer]
	SET	ComputerOUID = t.ComputerOUID,
		ComputerCN = t.ComputerCN,
		OperatingSystemID = t.OperatingSystemID,
		GUID = t.GUID
	FROM	#Computer AS t
	WHERE	Computer.ComputerID = t.ComputerID
	SET @count = @@ROWCOUNT
	DROP TABLE #Computer	-- Drop the temporary table
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ComputerUpdateByOUIDCN]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ComputerUpdateByOUIDCN]
GO
CREATE PROCEDURE [dbo].[ComputerUpdateByOUIDCN]
	@ComputerOUID		int,
	@ComputerCN		nvarchar(64),
	@OperatingSystemID	int = NULL,
	@GUID			binary(16) = NULL
AS
	DECLARE	@ID	int
	SET @ID = 0

	UPDATE	[dbo].[Computer]
	SET	@ID = ComputerID,
		OperatingSystemID = @OperatingSystemID,
		GUID = @GUID
	WHERE	ComputerOUID = @ComputerOUID
	  AND	ComputerCN = @ComputerCN
	RETURN @ID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ComputerUpdateBatchByOUIDCN]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ComputerUpdateBatchByOUIDCN]
GO
CREATE PROCEDURE dbo.[ComputerUpdateBatchByOUIDCN]
AS
	DECLARE @count int

	CREATE INDEX [TempComputerOUIDCN]
		ON #Computer (ComputerOUID, ComputerCN)

	UPDATE	[dbo].[Computer]
	SET	OperatingSystemID = t.OperatingSystemID,
		GUID = t.GUID
	FROM	#Computer AS t
	WHERE	Computer.ComputerOUID = t.ComputerOUID
	  AND	Computer.ComputerCN = t.ComputerCN
	SET @count = @@ROWCOUNT
	DROP TABLE #Computer	-- Drop the temporary table
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ComputerPutByOUIDCN]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ComputerPutByOUIDCN]
GO
CREATE PROCEDURE [dbo].[ComputerPutByOUIDCN]
	@ComputerOUID		int,
	@ComputerCN		nvarchar(64),
	@OperatingSystemID	int = NULL,
	@GUID			binary(16) = NULL
AS
	DECLARE @ID	int

	SELECT	@ID = ComputerID
	FROM	Computer
	WHERE	ComputerOUID = @ComputerOUID
	  AND	ComputerCN = @ComputerCN

	IF @ID IS NULL
		EXEC @ID = ComputerAdd @ComputerOUID,
			@ComputerCN,
			@OperatingSystemID,
			@GUID
	ELSE
		EXEC ComputerUpdateByOUIDCN @ComputerOUID,
			@ComputerCN,
			@OperatingSystemID,
			@GUID

	RETURN @ID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ComputerPutBatchByOUIDCN]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ComputerPutBatchByOUIDCN]
GO
CREATE PROCEDURE [dbo].[ComputerPutBatchByOUIDCN]
AS
	DECLARE @count AS int
	SET @count = 0

	CREATE INDEX [TempComputerOUIDCN]
		ON #Computer (ComputerOUID, ComputerCN)

	BEGIN TRANSACTION
	UPDATE [dbo].[Computer]
		SET	OperatingSystemID = t.OperatingSystemID,
			GUID = t.GUID
		FROM	#Computer AS t
		WHERE	Computer.ComputerOUID = t.ComputerOUID
		  AND	Computer.ComputerCN = t.ComputerCN
	SET @count = @@ROWCOUNT

	INSERT [dbo].[Computer] (
		ComputerOUID,
		ComputerCN,
		OperatingSystemID,
		GUID
	)
		SELECT	ComputerOUID,
			ComputerCN,
			OperatingSystemID,
			GUID
		FROM	#Computer AS t
		WHERE NOT EXISTS(	-- Current record doesn't exist
			SELECT * FROM [dbo].[Computer]
			WHERE	Computer.ComputerOUID = t.ComputerOUID
			  AND	Computer.ComputerCN = t.ComputerCN
		)
	SET @count = @count + @@ROWCOUNT
	DROP TABLE #Computer	-- Drop the temporary table
	COMMIT WORK
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ComputerRemoveBatch]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ComputerRemoveBatch]
GO

CREATE PROCEDURE [dbo].[ComputerRemoveBatch]
AS

	CREATE INDEX [TempComputerComputerRemoveBatch]
		ON #Computer (ComputerID)	

	-- Delete records from Computer identified by fields of [TempComputerComputerRemoveBatch]
	DELETE [dbo].[Computer]
	WHERE EXISTS(
			SELECT * FROM #Computer AS t
			WHERE	Computer.ComputerID = t.ComputerID
		)
	DROP TABLE #Computer      -- Drop the temporary table
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ComputerRemoveByOUIDCN]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ComputerRemoveByOUIDCN]
GO
CREATE PROCEDURE [dbo].[ComputerRemoveByOUIDCN]
	@ComputerOUID		int,
	@ComputerCN		nvarchar(64)
AS
	-- Computer deletes cascade to:
	--	Installation by FK_Installation_Computer
	--	InstallationHistory by FK_InstallationHistory_Computer
	--	InventoryReport by FK_InventoryReport_Computer
	--	SoftwareOccurrence by FK_SoftwareOccurrence_Computer
	--		SoftwareValue by FK_SoftwareValue_SoftwareOccurrence
	--	SoftwareFile by FK_SoftwareFile_Computer
	--		SoftwareFileProperty by FK_SoftwareFileProperty_SoftwareFile
	--	HardwareObject by FK_HardwareObject_Computer
	--		HardwareValue by FK_HardwareValue_HardwareObject
	--	ServiceProvider by FK_ServiceProvider_Computer
	--		ServiceProviderValue by FK_ServiceProviderValue_ServiceProvider
	--		ServiceProviderComponent by FK_ServiceProviderComponent_ServiceProvider
	--		ServiceProviderComponentValue by FK_ServiceProviderComponentValue_ServiceProvider
	--		ServiceUser by FK_ServiceUser_ServiceProvider
	--			ServiceUserOracle by FK_ServiceUserOracle_ServiceUser
	--		ServiceProviderApplicationOracle by FK_ServiceProviderApplicationOracle_ServiceProvider
	--			ServiceProviderApplicationUserOracle by FK_ServiceProviderApplicationUserOracle_Application
	--	NetworkDevice by FK_NetworkDevice_Computer
	--		NetworkDeviceCalculatedMember by FK_NetworkDeviceCalculatedMember_NetworkDevice
	--		NetworkDeviceSNMPInfo by FK_NetworkDeviceSNMPInfo_NetworkDevice
	--		NetworkDeviceAMTInfo by FK_NetworkDeviceAMTInfo_NetworkDevice
	--		NetworkDeviceVirtualizationInfo by FK_NetworkDeviceVirtualizationInfo_NetworkDevice
	--		NetworkDeviceDiscoveredBy by FK_NetworkDeviceDiscoveredBy_Device
	--		KnownOracleListener by FK_KnownOracleListener_NetworkDevice
	--			KnownOracleService by FK_KnownOracleService_KnownOracleListener
	--		AgentStatus by FK_AgentStatus_NetworkDevice
	--		AMTEventLog by FK_AMTEventLog_NetworkDevice
	--	ActionApplies by FK_ActionApplies_Computer
	--	SoftwareUsagePerWeek by FK_SoftwareUsagePerWeek_Computer
	--	ComputerUsage by FK_ComputerUsage_Computer
	--	DeviceEvent by FK_DeviceEvent_Computer
	--	SessionStateEvent by FK_SessionStateEvent_Computer
	--	GeneralSecurityEvent by FK_GeneralSecurityEvent_Computer
	--	WakeOnLANStatus by FK_WOLStatus_Computer
	-- Computer deletes may fail due to non-cascading FKs:
	--	(through ServiceProvider by FK_ServiceProvider_Computer)
	--		ServiceProvider by FK_ServiceProvider_Parent
	--	(through NetworkDevice by FK_NetworkDevice_Computer)
	--		NetworkDevice by FK_NetworkDevice_Duplicate
	--		NetworkDeviceParent by FK_NetworkDeviceChild_NetworkDevice
	--		NetworkDeviceParent by FK_NetworkDeviceParent_NetworkDevice
	--		KnownOracleService by FK_KnownOracleService_NetworkDevice
	--		ActionApplies by FK_ActionApplies_DeviceID
	DELETE	[dbo].[Computer]
	WHERE	ComputerOUID = @ComputerOUID
	  AND	ComputerCN = @ComputerCN
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ComputerRemoveAllByOUID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ComputerRemoveAllByOUID]
GO
CREATE PROCEDURE [dbo].[ComputerRemoveAllByOUID]
	@ComputerOUID		int
AS
	DELETE	[dbo].[Computer]
	WHERE	ComputerOUID = @ComputerOUID
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ComputerRemoveAllByGUID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ComputerRemoveAllByGUID]
GO
CREATE PROCEDURE [dbo].[ComputerRemoveAllByGUID]
	@GUID			binary(16) = NULL
AS
	DELETE	[dbo].[Computer]
	WHERE	(GUID = @GUID OR (GUID IS NULL AND @GUID IS NULL))
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ComputerRemoveAllByCN]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ComputerRemoveAllByCN]
GO
CREATE PROCEDURE [dbo].[ComputerRemoveAllByCN]
	@ComputerCN		nvarchar(64)
AS
	DELETE	[dbo].[Computer]
	WHERE	ComputerCN = @ComputerCN
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ComputerRemoveAll]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ComputerRemoveAll]
GO
CREATE PROCEDURE [dbo].[ComputerRemoveAll]
	
AS
	DELETE	[dbo].[Computer]
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ComputerReplaceSubsetByOUID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ComputerReplaceSubsetByOUID]
GO
-- Replace the record subset selected by (@ComputerOUID)
-- using unique identifier (ComputerOUID, ComputerCN)
-- updating fields (OperatingSystemID, GUID)
CREATE PROCEDURE [dbo].[ComputerReplaceSubsetByOUID]
	@ComputerOUID		int
AS
	DECLARE @count AS int
	SET @count = 0

	CREATE INDEX [TempComputerByOUID]
		ON #Computer (ComputerOUID, ComputerCN)

	BEGIN TRANSACTION
	DELETE [Computer]
		WHERE	ComputerOUID = @ComputerOUID
		AND NOT EXISTS(		-- Replacement record doesn't exist
			SELECT * FROM #Computer AS t
			WHERE	Computer.ComputerOUID = t.ComputerOUID
			  AND	Computer.ComputerCN = t.ComputerCN
		)

	UPDATE [dbo].[Computer]
		SET	OperatingSystemID = t.OperatingSystemID,
			GUID = t.GUID
		FROM	#Computer AS t
		WHERE	Computer.ComputerOUID = t.ComputerOUID
		  AND	Computer.ComputerCN = t.ComputerCN
	SET @count = @@ROWCOUNT

	INSERT [Computer] (
		ComputerOUID,
		ComputerCN,
		OperatingSystemID,
		GUID
	)
		SELECT	ComputerOUID,
			ComputerCN,
			OperatingSystemID,
			GUID
		FROM	#Computer AS t
		WHERE NOT EXISTS(	-- Current record doesn't exist
			SELECT * FROM [Computer]
			WHERE	Computer.ComputerOUID = t.ComputerOUID
			  AND	Computer.ComputerCN = t.ComputerCN
		)
	SET @count = @count + @@ROWCOUNT
	DROP TABLE #Computer	-- Drop the temporary table
	COMMIT WORK
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ComputerReplaceSubsetByGUID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ComputerReplaceSubsetByGUID]
GO
-- Replace the record subset selected by (@GUID)
-- using unique identifier (ComputerOUID, ComputerCN)
-- updating fields (OperatingSystemID)
CREATE PROCEDURE [dbo].[ComputerReplaceSubsetByGUID]
	@GUID			binary(16) = NULL
AS
	DECLARE @count AS int
	SET @count = 0

	CREATE INDEX [TempComputerByGUID]
		ON #Computer (ComputerOUID, ComputerCN)

	BEGIN TRANSACTION
	DELETE [Computer]
		WHERE	(GUID = @GUID OR (GUID IS NULL AND @GUID IS NULL))
		AND NOT EXISTS(		-- Replacement record doesn't exist
			SELECT * FROM #Computer AS t
			WHERE	Computer.ComputerOUID = t.ComputerOUID
			  AND	Computer.ComputerCN = t.ComputerCN
		)

	UPDATE [dbo].[Computer]
		SET	OperatingSystemID = t.OperatingSystemID
		FROM	#Computer AS t
		WHERE	Computer.ComputerOUID = t.ComputerOUID
		  AND	Computer.ComputerCN = t.ComputerCN
	SET @count = @@ROWCOUNT

	INSERT [Computer] (
		ComputerOUID,
		ComputerCN,
		OperatingSystemID,
		GUID
	)
		SELECT	ComputerOUID,
			ComputerCN,
			OperatingSystemID,
			GUID
		FROM	#Computer AS t
		WHERE NOT EXISTS(	-- Current record doesn't exist
			SELECT * FROM [Computer]
			WHERE	Computer.ComputerOUID = t.ComputerOUID
			  AND	Computer.ComputerCN = t.ComputerCN
		)
	SET @count = @count + @@ROWCOUNT
	DROP TABLE #Computer	-- Drop the temporary table
	COMMIT WORK
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ComputerReplaceSubsetByCN]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ComputerReplaceSubsetByCN]
GO
-- Replace the record subset selected by (@ComputerCN)
-- using unique identifier (ComputerOUID, ComputerCN)
-- updating fields (OperatingSystemID, GUID)
CREATE PROCEDURE [dbo].[ComputerReplaceSubsetByCN]
	@ComputerCN		nvarchar(64)
AS
	DECLARE @count AS int
	SET @count = 0

	CREATE INDEX [TempComputerByCN]
		ON #Computer (ComputerOUID, ComputerCN)

	BEGIN TRANSACTION
	DELETE [Computer]
		WHERE	ComputerCN = @ComputerCN
		AND NOT EXISTS(		-- Replacement record doesn't exist
			SELECT * FROM #Computer AS t
			WHERE	Computer.ComputerOUID = t.ComputerOUID
			  AND	Computer.ComputerCN = t.ComputerCN
		)

	UPDATE [dbo].[Computer]
		SET	OperatingSystemID = t.OperatingSystemID,
			GUID = t.GUID
		FROM	#Computer AS t
		WHERE	Computer.ComputerOUID = t.ComputerOUID
		  AND	Computer.ComputerCN = t.ComputerCN
	SET @count = @@ROWCOUNT

	INSERT [Computer] (
		ComputerOUID,
		ComputerCN,
		OperatingSystemID,
		GUID
	)
		SELECT	ComputerOUID,
			ComputerCN,
			OperatingSystemID,
			GUID
		FROM	#Computer AS t
		WHERE NOT EXISTS(	-- Current record doesn't exist
			SELECT * FROM [Computer]
			WHERE	Computer.ComputerOUID = t.ComputerOUID
			  AND	Computer.ComputerCN = t.ComputerCN
		)
	SET @count = @count + @@ROWCOUNT
	DROP TABLE #Computer	-- Drop the temporary table
	COMMIT WORK
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ADSDOUGetByDomainIDRDN]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ADSDOUGetByDomainIDRDN]
GO
CREATE PROCEDURE [dbo].[ADSDOUGetByDomainIDRDN]
	@DomainID		int,
	@RDN			nvarchar(400)
AS
	SELECT	DomainID,
		RDN,
		GUID,
		BlockInheritance
	FROM	[dbo].[ADSDOU]
	WHERE	DomainID = @DomainID
	  AND	RDN = @RDN
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ADSDOUGetAllByDomainID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ADSDOUGetAllByDomainID]
GO
CREATE PROCEDURE [dbo].[ADSDOUGetAllByDomainID]
	@DomainID		int
AS
	SELECT	DomainID,
		RDN,
		GUID,
		BlockInheritance
	FROM	[dbo].[ADSDOU]
	WHERE	DomainID = @DomainID
	ORDER BY RDN
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ADSDOUGetByGUID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ADSDOUGetByGUID]
GO
CREATE PROCEDURE [dbo].[ADSDOUGetByGUID]
	@GUID			binary(16)
AS
	SELECT	DomainID,
		RDN,
		GUID,
		BlockInheritance
	FROM	[dbo].[ADSDOU]
	WHERE	GUID = @GUID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ADSDOUGetAll]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ADSDOUGetAll]
GO
CREATE PROCEDURE [dbo].[ADSDOUGetAll]
AS
	SELECT	DomainID,
		RDN,
		GUID,
		BlockInheritance
	FROM	[dbo].[ADSDOU]
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ADSDOUAdd]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ADSDOUAdd]
GO
CREATE PROCEDURE [dbo].[ADSDOUAdd]
	@DomainID		int,
	@RDN			nvarchar(400),
	@GUID			binary(16),
	@BlockInheritance	bit = 0
AS
	INSERT INTO  dbo.ADSDOU (
		DomainID,
		RDN,
		GUID,
		BlockInheritance
	)
	VALUES (
		@DomainID,
		@RDN,
		@GUID,
		@BlockInheritance
	)
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ADSDOUSchema]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ADSDOUSchema]
GO
CREATE PROCEDURE [dbo].[ADSDOUSchema]
AS
	SELECT
	'IF OBJECT_ID(''tempdb..#ADSDOU'') IS NULL' + CAST(0x0A AS CHAR(1)) +
	'	CREATE TABLE #ADSDOU (' + CAST(0x0A AS CHAR(1)) +
	'		DomainID		int NOT NULL,' + CAST(0x0A AS CHAR(1)) +
	'		RDN			nvarchar(400) COLLATE database_default NOT NULL,' + CAST(0x0A AS CHAR(1)) +
	'		GUID			binary(16) NOT NULL,' + CAST(0x0A AS CHAR(1)) +
	'		BlockInheritance	bit NOT NULL DEFAULT 0' + CAST(0x0A AS CHAR(1)) +
	'	)' + CAST(0x0A AS CHAR(1)) +
	'ELSE' + CAST(0x0A AS CHAR(1)) +
	'	DELETE FROM #ADSDOU' + CAST(0x0A AS CHAR(1)) +
	'' AS SQL
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ADSDOUTempAdd]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ADSDOUTempAdd]
GO
CREATE PROCEDURE dbo.[ADSDOUTempAdd]
	@DomainID		int,
	@RDN			nvarchar(400),
	@GUID			binary(16),
	@BlockInheritance	bit = 0
AS
	INSERT INTO #ADSDOU (
		DomainID,
		RDN,
		GUID,
		BlockInheritance
	)
	VALUES (
		@DomainID,
		@RDN,
		@GUID,
		@BlockInheritance
	)
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ADSDOUAddBatch]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ADSDOUAddBatch]
GO
CREATE PROCEDURE dbo.[ADSDOUAddBatch]
AS
	DECLARE @count int
	INSERT dbo.ADSDOU (
		DomainID,
		RDN,
		GUID,
		BlockInheritance
	)
		SELECT	DomainID,
			RDN,
			GUID,
			BlockInheritance
		FROM #ADSDOU
	SET @count = @@ROWCOUNT
	DROP TABLE #ADSDOU	-- Drop temporary table
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ADSDOUUpdateByDomainIDRDN]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ADSDOUUpdateByDomainIDRDN]
GO
CREATE PROCEDURE [dbo].[ADSDOUUpdateByDomainIDRDN]
	@DomainID		int,
	@RDN			nvarchar(400),
	@GUID			binary(16),
	@BlockInheritance	bit = 0
AS
	UPDATE	[dbo].[ADSDOU]
	SET	GUID = @GUID,
		BlockInheritance = @BlockInheritance
	WHERE	DomainID = @DomainID
	  AND	RDN = @RDN
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ADSDOUUpdateBatchByDomainIDRDN]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ADSDOUUpdateBatchByDomainIDRDN]
GO
CREATE PROCEDURE dbo.[ADSDOUUpdateBatchByDomainIDRDN]
AS
	DECLARE @count int

	CREATE INDEX [TempADSDOUDomainIDRDN]
		ON #ADSDOU (DomainID, RDN)

	UPDATE	[dbo].[ADSDOU]
	SET	GUID = t.GUID,
		BlockInheritance = t.BlockInheritance
	FROM	#ADSDOU AS t
	WHERE	ADSDOU.DomainID = t.DomainID
	  AND	ADSDOU.RDN = t.RDN
	SET @count = @@ROWCOUNT
	DROP TABLE #ADSDOU	-- Drop the temporary table
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ADSDOUPutByDomainIDRDN]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ADSDOUPutByDomainIDRDN]
GO
CREATE PROCEDURE [dbo].[ADSDOUPutByDomainIDRDN]
	@DomainID		int,
	@RDN			nvarchar(400),
	@GUID			binary(16),
	@BlockInheritance	bit = 0
AS
	IF NOT EXISTS(
		SELECT	1
		FROM	dbo.ADSDOU
		WHERE	DomainID = @DomainID
		  AND	RDN = @RDN
	)
		EXEC ADSDOUAdd @DomainID,
			@RDN,
			@GUID,
			@BlockInheritance
	ELSE
		EXEC ADSDOUUpdateByDomainIDRDN @DomainID,
			@RDN,
			@GUID,
			@BlockInheritance
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ADSDOUPutBatchByDomainIDRDN]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ADSDOUPutBatchByDomainIDRDN]
GO
CREATE PROCEDURE [dbo].[ADSDOUPutBatchByDomainIDRDN]
AS
	DECLARE @count AS int
	SET @count = 0

	CREATE INDEX [TempADSDOUDomainIDRDN]
		ON #ADSDOU (DomainID, RDN)

	BEGIN TRANSACTION
	UPDATE [dbo].[ADSDOU]
		SET	GUID = t.GUID,
			BlockInheritance = t.BlockInheritance
		FROM	#ADSDOU AS t
		WHERE	ADSDOU.DomainID = t.DomainID
		  AND	ADSDOU.RDN = t.RDN
	SET @count = @@ROWCOUNT

	INSERT [dbo].[ADSDOU] (
		DomainID,
		RDN,
		GUID,
		BlockInheritance
	)
		SELECT	DomainID,
			RDN,
			GUID,
			BlockInheritance
		FROM	#ADSDOU AS t
		WHERE NOT EXISTS(	-- Current record doesn't exist
			SELECT * FROM [dbo].[ADSDOU]
			WHERE	ADSDOU.DomainID = t.DomainID
			  AND	ADSDOU.RDN = t.RDN
		)
	SET @count = @count + @@ROWCOUNT
	DROP TABLE #ADSDOU	-- Drop the temporary table
	COMMIT WORK
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ADSDOURemoveBatch]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ADSDOURemoveBatch]
GO

CREATE PROCEDURE [dbo].[ADSDOURemoveBatch]
AS

	CREATE INDEX [TempADSDOUADSDOURemoveBatch]
		ON #ADSDOU (DomainID, RDN)	

	-- Delete records from ADSDOU identified by fields of [TempADSDOUADSDOURemoveBatch]
	DELETE [dbo].[ADSDOU]
	WHERE EXISTS(
			SELECT * FROM #ADSDOU AS t
			WHERE	ADSDOU.DomainID = t.DomainID
			  AND	ADSDOU.RDN = t.RDN
		)
	DROP TABLE #ADSDOU      -- Drop the temporary table
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ADSDOURemoveByDomainIDRDN]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ADSDOURemoveByDomainIDRDN]
GO
CREATE PROCEDURE [dbo].[ADSDOURemoveByDomainIDRDN]
	@DomainID		int,
	@RDN			nvarchar(400)
AS
	DELETE	[dbo].[ADSDOU]
	WHERE	DomainID = @DomainID
	  AND	RDN = @RDN
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ADSDOURemoveAllByDomainID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ADSDOURemoveAllByDomainID]
GO
CREATE PROCEDURE [dbo].[ADSDOURemoveAllByDomainID]
	@DomainID		int
AS
	DELETE	[dbo].[ADSDOU]
	WHERE	DomainID = @DomainID
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ADSDOURemoveAll]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ADSDOURemoveAll]
GO
CREATE PROCEDURE [dbo].[ADSDOURemoveAll]
	
AS
	DELETE	[dbo].[ADSDOU]
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ADSDOUReplaceSubsetByDomainID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ADSDOUReplaceSubsetByDomainID]
GO
-- Replace the record subset selected by (@DomainID)
-- using unique identifier (DomainID, RDN)
-- updating fields (GUID, BlockInheritance)
CREATE PROCEDURE [dbo].[ADSDOUReplaceSubsetByDomainID]
	@DomainID		int
AS
	DECLARE @count AS int
	SET @count = 0

	CREATE INDEX [TempADSDOUByDomainID]
		ON #ADSDOU (DomainID, RDN)

	BEGIN TRANSACTION
	DELETE [ADSDOU]
		WHERE	DomainID = @DomainID
		AND NOT EXISTS(		-- Replacement record doesn't exist
			SELECT * FROM #ADSDOU AS t
			WHERE	ADSDOU.DomainID = t.DomainID
			  AND	ADSDOU.RDN = t.RDN
		)

	UPDATE [dbo].[ADSDOU]
		SET	GUID = t.GUID,
			BlockInheritance = t.BlockInheritance
		FROM	#ADSDOU AS t
		WHERE	ADSDOU.DomainID = t.DomainID
		  AND	ADSDOU.RDN = t.RDN
	SET @count = @@ROWCOUNT

	INSERT [ADSDOU] (
		DomainID,
		RDN,
		GUID,
		BlockInheritance
	)
		SELECT	DomainID,
			RDN,
			GUID,
			BlockInheritance
		FROM	#ADSDOU AS t
		WHERE NOT EXISTS(	-- Current record doesn't exist
			SELECT * FROM [ADSDOU]
			WHERE	ADSDOU.DomainID = t.DomainID
			  AND	ADSDOU.RDN = t.RDN
		)
	SET @count = @count + @@ROWCOUNT
	DROP TABLE #ADSDOU	-- Drop the temporary table
	COMMIT WORK
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ADComputerGetByDomainIDComputerCNComputerOURDN]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ADComputerGetByDomainIDComputerCNComputerOURDN]
GO
CREATE PROCEDURE [dbo].[ADComputerGetByDomainIDComputerCNComputerOURDN]
	@DomainID		int,
	@ComputerCN		nvarchar(64),
	@ComputerOURDN		nvarchar(384)
AS
	SELECT	DomainID,
		ComputerCN,
		ComputerOURDN,
		GUID
	FROM	[dbo].[ADComputer]
	WHERE	DomainID = @DomainID
	  AND	ComputerCN = @ComputerCN
	  AND	ComputerOURDN = @ComputerOURDN
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ADComputerGetAllByDomainID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ADComputerGetAllByDomainID]
GO
CREATE PROCEDURE [dbo].[ADComputerGetAllByDomainID]
	@DomainID		int
AS
	SELECT	DomainID,
		ComputerCN,
		ComputerOURDN,
		GUID
	FROM	[dbo].[ADComputer]
	WHERE	DomainID = @DomainID
	ORDER BY ComputerCN, ComputerOURDN
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ADComputerGetByGUID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ADComputerGetByGUID]
GO
CREATE PROCEDURE [dbo].[ADComputerGetByGUID]
	@GUID			binary(16)
AS
	SELECT	DomainID,
		ComputerCN,
		ComputerOURDN,
		GUID
	FROM	[dbo].[ADComputer]
	WHERE	GUID = @GUID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ADComputerGetAll]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ADComputerGetAll]
GO
CREATE PROCEDURE [dbo].[ADComputerGetAll]
AS
	SELECT	DomainID,
		ComputerCN,
		ComputerOURDN,
		GUID
	FROM	[dbo].[ADComputer]
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ADComputerAdd]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ADComputerAdd]
GO
CREATE PROCEDURE [dbo].[ADComputerAdd]
	@DomainID		int,
	@ComputerCN		nvarchar(64),
	@ComputerOURDN		nvarchar(384),
	@GUID			binary(16)
AS
	INSERT INTO  dbo.ADComputer (
		DomainID,
		ComputerCN,
		ComputerOURDN,
		GUID
	)
	VALUES (
		@DomainID,
		@ComputerCN,
		@ComputerOURDN,
		@GUID
	)
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ADComputerSchema]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ADComputerSchema]
GO
CREATE PROCEDURE [dbo].[ADComputerSchema]
AS
	SELECT
	'IF OBJECT_ID(''tempdb..#ADComputer'') IS NULL' + CAST(0x0A AS CHAR(1)) +
	'	CREATE TABLE #ADComputer (' + CAST(0x0A AS CHAR(1)) +
	'		DomainID		int NOT NULL,' + CAST(0x0A AS CHAR(1)) +
	'		ComputerCN		nvarchar(64) COLLATE database_default NOT NULL,' + CAST(0x0A AS CHAR(1)) +
	'		ComputerOURDN		nvarchar(384) COLLATE database_default NOT NULL,' + CAST(0x0A AS CHAR(1)) +
	'		GUID			binary(16) NOT NULL' + CAST(0x0A AS CHAR(1)) +
	'	)' + CAST(0x0A AS CHAR(1)) +
	'ELSE' + CAST(0x0A AS CHAR(1)) +
	'	DELETE FROM #ADComputer' + CAST(0x0A AS CHAR(1)) +
	'' AS SQL
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ADComputerTempAdd]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ADComputerTempAdd]
GO
CREATE PROCEDURE dbo.[ADComputerTempAdd]
	@DomainID		int,
	@ComputerCN		nvarchar(64),
	@ComputerOURDN		nvarchar(384),
	@GUID			binary(16)
AS
	INSERT INTO #ADComputer (
		DomainID,
		ComputerCN,
		ComputerOURDN,
		GUID
	)
	VALUES (
		@DomainID,
		@ComputerCN,
		@ComputerOURDN,
		@GUID
	)
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ADComputerAddBatch]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ADComputerAddBatch]
GO
CREATE PROCEDURE dbo.[ADComputerAddBatch]
AS
	DECLARE @count int
	INSERT dbo.ADComputer (
		DomainID,
		ComputerCN,
		ComputerOURDN,
		GUID
	)
		SELECT	DomainID,
			ComputerCN,
			ComputerOURDN,
			GUID
		FROM #ADComputer
	SET @count = @@ROWCOUNT
	DROP TABLE #ADComputer	-- Drop temporary table
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ADComputerUpdateByDomainIDComputerCNComputerOURDN]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ADComputerUpdateByDomainIDComputerCNComputerOURDN]
GO
CREATE PROCEDURE [dbo].[ADComputerUpdateByDomainIDComputerCNComputerOURDN]
	@DomainID		int,
	@ComputerCN		nvarchar(64),
	@ComputerOURDN		nvarchar(384),
	@GUID			binary(16)
AS
	UPDATE	[dbo].[ADComputer]
	SET	GUID = @GUID
	WHERE	DomainID = @DomainID
	  AND	ComputerCN = @ComputerCN
	  AND	ComputerOURDN = @ComputerOURDN
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ADComputerUpdateBatchByDomainIDComputerCNComputerOURDN]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ADComputerUpdateBatchByDomainIDComputerCNComputerOURDN]
GO
CREATE PROCEDURE dbo.[ADComputerUpdateBatchByDomainIDComputerCNComputerOURDN]
AS
	DECLARE @count int

	CREATE INDEX [TempADComputerDomainIDComputerCNComputerOURDN]
		ON #ADComputer (DomainID, ComputerCN, ComputerOURDN)

	UPDATE	[dbo].[ADComputer]
	SET	GUID = t.GUID
	FROM	#ADComputer AS t
	WHERE	ADComputer.DomainID = t.DomainID
	  AND	ADComputer.ComputerCN = t.ComputerCN
	  AND	ADComputer.ComputerOURDN = t.ComputerOURDN
	SET @count = @@ROWCOUNT
	DROP TABLE #ADComputer	-- Drop the temporary table
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ADComputerPutByDomainIDComputerCNComputerOURDN]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ADComputerPutByDomainIDComputerCNComputerOURDN]
GO
CREATE PROCEDURE [dbo].[ADComputerPutByDomainIDComputerCNComputerOURDN]
	@DomainID		int,
	@ComputerCN		nvarchar(64),
	@ComputerOURDN		nvarchar(384),
	@GUID			binary(16)
AS
	IF NOT EXISTS(
		SELECT	1
		FROM	dbo.ADComputer
		WHERE	DomainID = @DomainID
		  AND	ComputerCN = @ComputerCN
		  AND	ComputerOURDN = @ComputerOURDN
	)
		EXEC ADComputerAdd @DomainID,
			@ComputerCN,
			@ComputerOURDN,
			@GUID
	ELSE
		EXEC ADComputerUpdateByDomainIDComputerCNComputerOURDN @DomainID,
			@ComputerCN,
			@ComputerOURDN,
			@GUID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ADComputerPutBatchByDomainIDComputerCNComputerOURDN]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ADComputerPutBatchByDomainIDComputerCNComputerOURDN]
GO
CREATE PROCEDURE [dbo].[ADComputerPutBatchByDomainIDComputerCNComputerOURDN]
AS
	DECLARE @count AS int
	SET @count = 0

	CREATE INDEX [TempADComputerDomainIDComputerCNComputerOURDN]
		ON #ADComputer (DomainID, ComputerCN, ComputerOURDN)

	BEGIN TRANSACTION
	UPDATE [dbo].[ADComputer]
		SET	GUID = t.GUID
		FROM	#ADComputer AS t
		WHERE	ADComputer.DomainID = t.DomainID
		  AND	ADComputer.ComputerCN = t.ComputerCN
		  AND	ADComputer.ComputerOURDN = t.ComputerOURDN
	SET @count = @@ROWCOUNT

	INSERT [dbo].[ADComputer] (
		DomainID,
		ComputerCN,
		ComputerOURDN,
		GUID
	)
		SELECT	DomainID,
			ComputerCN,
			ComputerOURDN,
			GUID
		FROM	#ADComputer AS t
		WHERE NOT EXISTS(	-- Current record doesn't exist
			SELECT * FROM [dbo].[ADComputer]
			WHERE	ADComputer.DomainID = t.DomainID
			  AND	ADComputer.ComputerCN = t.ComputerCN
			  AND	ADComputer.ComputerOURDN = t.ComputerOURDN
		)
	SET @count = @count + @@ROWCOUNT
	DROP TABLE #ADComputer	-- Drop the temporary table
	COMMIT WORK
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ADComputerRemoveBatch]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ADComputerRemoveBatch]
GO

CREATE PROCEDURE [dbo].[ADComputerRemoveBatch]
AS

	CREATE INDEX [TempADComputerADComputerRemoveBatch]
		ON #ADComputer (DomainID, ComputerCN, ComputerOURDN)	

	-- Delete records from ADComputer identified by fields of [TempADComputerADComputerRemoveBatch]
	DELETE [dbo].[ADComputer]
	WHERE EXISTS(
			SELECT * FROM #ADComputer AS t
			WHERE	ADComputer.DomainID = t.DomainID
			  AND	ADComputer.ComputerCN = t.ComputerCN
			  AND	ADComputer.ComputerOURDN = t.ComputerOURDN
		)
	DROP TABLE #ADComputer      -- Drop the temporary table
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ADComputerRemoveByDomainIDComputerCNComputerOURDN]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ADComputerRemoveByDomainIDComputerCNComputerOURDN]
GO
CREATE PROCEDURE [dbo].[ADComputerRemoveByDomainIDComputerCNComputerOURDN]
	@DomainID		int,
	@ComputerCN		nvarchar(64),
	@ComputerOURDN		nvarchar(384)
AS
	DELETE	[dbo].[ADComputer]
	WHERE	DomainID = @DomainID
	  AND	ComputerCN = @ComputerCN
	  AND	ComputerOURDN = @ComputerOURDN
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ADComputerRemoveAllByDomainID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ADComputerRemoveAllByDomainID]
GO
CREATE PROCEDURE [dbo].[ADComputerRemoveAllByDomainID]
	@DomainID		int
AS
	DELETE	[dbo].[ADComputer]
	WHERE	DomainID = @DomainID
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ADComputerRemoveAll]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ADComputerRemoveAll]
GO
CREATE PROCEDURE [dbo].[ADComputerRemoveAll]
	
AS
	DELETE	[dbo].[ADComputer]
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ADComputerReplaceSubsetByDomainID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ADComputerReplaceSubsetByDomainID]
GO
-- Replace the record subset selected by (@DomainID)
-- using unique identifier (DomainID, ComputerCN, ComputerOURDN)
-- updating fields (GUID)
CREATE PROCEDURE [dbo].[ADComputerReplaceSubsetByDomainID]
	@DomainID		int
AS
	DECLARE @count AS int
	SET @count = 0

	CREATE INDEX [TempADComputerByDomainID]
		ON #ADComputer (DomainID, ComputerCN, ComputerOURDN)

	BEGIN TRANSACTION
	DELETE [ADComputer]
		WHERE	DomainID = @DomainID
		AND NOT EXISTS(		-- Replacement record doesn't exist
			SELECT * FROM #ADComputer AS t
			WHERE	ADComputer.DomainID = t.DomainID
			  AND	ADComputer.ComputerCN = t.ComputerCN
			  AND	ADComputer.ComputerOURDN = t.ComputerOURDN
		)

	UPDATE [dbo].[ADComputer]
		SET	GUID = t.GUID
		FROM	#ADComputer AS t
		WHERE	ADComputer.DomainID = t.DomainID
		  AND	ADComputer.ComputerCN = t.ComputerCN
		  AND	ADComputer.ComputerOURDN = t.ComputerOURDN
	SET @count = @@ROWCOUNT

	INSERT [ADComputer] (
		DomainID,
		ComputerCN,
		ComputerOURDN,
		GUID
	)
		SELECT	DomainID,
			ComputerCN,
			ComputerOURDN,
			GUID
		FROM	#ADComputer AS t
		WHERE NOT EXISTS(	-- Current record doesn't exist
			SELECT * FROM [ADComputer]
			WHERE	ADComputer.DomainID = t.DomainID
			  AND	ADComputer.ComputerCN = t.ComputerCN
			  AND	ADComputer.ComputerOURDN = t.ComputerOURDN
		)
	SET @count = @count + @@ROWCOUNT
	DROP TABLE #ADComputer	-- Drop the temporary table
	COMMIT WORK
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ADUserGetByDomainIDUserCNUserOURDN]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ADUserGetByDomainIDUserCNUserOURDN]
GO
CREATE PROCEDURE [dbo].[ADUserGetByDomainIDUserCNUserOURDN]
	@DomainID		int,
	@UserCN			nvarchar(64),
	@UserOURDN		nvarchar(384)
AS
	SELECT	DomainID,
		UserCN,
		UserOURDN,
		GUID,
		SAMAccountName
	FROM	[dbo].[ADUser]
	WHERE	DomainID = @DomainID
	  AND	UserCN = @UserCN
	  AND	UserOURDN = @UserOURDN
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ADUserGetAllByDomainID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ADUserGetAllByDomainID]
GO
CREATE PROCEDURE [dbo].[ADUserGetAllByDomainID]
	@DomainID		int
AS
	SELECT	DomainID,
		UserCN,
		UserOURDN,
		GUID,
		SAMAccountName
	FROM	[dbo].[ADUser]
	WHERE	DomainID = @DomainID
	ORDER BY UserCN, UserOURDN
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ADUserGetByGUID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ADUserGetByGUID]
GO
CREATE PROCEDURE [dbo].[ADUserGetByGUID]
	@GUID			binary(16) = NULL
AS
	SELECT	DomainID,
		UserCN,
		UserOURDN,
		GUID,
		SAMAccountName
	FROM	[dbo].[ADUser]
	WHERE	(GUID = @GUID OR (GUID IS NULL AND @GUID IS NULL))
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ADUserGetAll]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ADUserGetAll]
GO
CREATE PROCEDURE [dbo].[ADUserGetAll]
AS
	SELECT	DomainID,
		UserCN,
		UserOURDN,
		GUID,
		SAMAccountName
	FROM	[dbo].[ADUser]
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ADUserAdd]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ADUserAdd]
GO
CREATE PROCEDURE [dbo].[ADUserAdd]
	@DomainID		int,
	@UserCN			nvarchar(64),
	@UserOURDN		nvarchar(384),
	@GUID			binary(16) = NULL,
	@SAMAccountName		nvarchar(20) = NULL
AS
	INSERT INTO  dbo.ADUser (
		DomainID,
		UserCN,
		UserOURDN,
		GUID,
		SAMAccountName
	)
	VALUES (
		@DomainID,
		@UserCN,
		@UserOURDN,
		@GUID,
		@SAMAccountName
	)
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ADUserSchema]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ADUserSchema]
GO
CREATE PROCEDURE [dbo].[ADUserSchema]
AS
	SELECT
	'IF OBJECT_ID(''tempdb..#ADUser'') IS NULL' + CAST(0x0A AS CHAR(1)) +
	'	CREATE TABLE #ADUser (' + CAST(0x0A AS CHAR(1)) +
	'		DomainID		int NOT NULL,' + CAST(0x0A AS CHAR(1)) +
	'		UserCN			nvarchar(64) COLLATE database_default NOT NULL,' + CAST(0x0A AS CHAR(1)) +
	'		UserOURDN		nvarchar(384) COLLATE database_default NOT NULL,' + CAST(0x0A AS CHAR(1)) +
	'		GUID			binary(16) NULL,' + CAST(0x0A AS CHAR(1)) +
	'		SAMAccountName		nvarchar(20) COLLATE database_default NULL' + CAST(0x0A AS CHAR(1)) +
	'	)' + CAST(0x0A AS CHAR(1)) +
	'ELSE' + CAST(0x0A AS CHAR(1)) +
	'	DELETE FROM #ADUser' + CAST(0x0A AS CHAR(1)) +
	'' AS SQL
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ADUserTempAdd]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ADUserTempAdd]
GO
CREATE PROCEDURE dbo.[ADUserTempAdd]
	@DomainID		int,
	@UserCN			nvarchar(64),
	@UserOURDN		nvarchar(384),
	@GUID			binary(16) = NULL,
	@SAMAccountName		nvarchar(20) = NULL
AS
	INSERT INTO #ADUser (
		DomainID,
		UserCN,
		UserOURDN,
		GUID,
		SAMAccountName
	)
	VALUES (
		@DomainID,
		@UserCN,
		@UserOURDN,
		@GUID,
		@SAMAccountName
	)
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ADUserAddBatch]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ADUserAddBatch]
GO
CREATE PROCEDURE dbo.[ADUserAddBatch]
AS
	DECLARE @count int
	INSERT dbo.ADUser (
		DomainID,
		UserCN,
		UserOURDN,
		GUID,
		SAMAccountName
	)
		SELECT	DomainID,
			UserCN,
			UserOURDN,
			GUID,
			SAMAccountName
		FROM #ADUser
	SET @count = @@ROWCOUNT
	DROP TABLE #ADUser	-- Drop temporary table
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ADUserUpdateByDomainIDUserCNUserOURDN]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ADUserUpdateByDomainIDUserCNUserOURDN]
GO
CREATE PROCEDURE [dbo].[ADUserUpdateByDomainIDUserCNUserOURDN]
	@DomainID		int,
	@UserCN			nvarchar(64),
	@UserOURDN		nvarchar(384),
	@GUID			binary(16) = NULL,
	@SAMAccountName		nvarchar(20) = NULL
AS
	UPDATE	[dbo].[ADUser]
	SET	GUID = @GUID,
		SAMAccountName = @SAMAccountName
	WHERE	DomainID = @DomainID
	  AND	UserCN = @UserCN
	  AND	UserOURDN = @UserOURDN
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ADUserUpdateBatchByDomainIDUserCNUserOURDN]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ADUserUpdateBatchByDomainIDUserCNUserOURDN]
GO
CREATE PROCEDURE dbo.[ADUserUpdateBatchByDomainIDUserCNUserOURDN]
AS
	DECLARE @count int

	CREATE INDEX [TempADUserDomainIDUserCNUserOURDN]
		ON #ADUser (DomainID, UserCN, UserOURDN)

	UPDATE	[dbo].[ADUser]
	SET	GUID = t.GUID,
		SAMAccountName = t.SAMAccountName
	FROM	#ADUser AS t
	WHERE	ADUser.DomainID = t.DomainID
	  AND	ADUser.UserCN = t.UserCN
	  AND	ADUser.UserOURDN = t.UserOURDN
	SET @count = @@ROWCOUNT
	DROP TABLE #ADUser	-- Drop the temporary table
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ADUserPutByDomainIDUserCNUserOURDN]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ADUserPutByDomainIDUserCNUserOURDN]
GO
CREATE PROCEDURE [dbo].[ADUserPutByDomainIDUserCNUserOURDN]
	@DomainID		int,
	@UserCN			nvarchar(64),
	@UserOURDN		nvarchar(384),
	@GUID			binary(16) = NULL,
	@SAMAccountName		nvarchar(20) = NULL
AS
	IF NOT EXISTS(
		SELECT	1
		FROM	dbo.ADUser
		WHERE	DomainID = @DomainID
		  AND	UserCN = @UserCN
		  AND	UserOURDN = @UserOURDN
	)
		EXEC ADUserAdd @DomainID,
			@UserCN,
			@UserOURDN,
			@GUID,
			@SAMAccountName
	ELSE
		EXEC ADUserUpdateByDomainIDUserCNUserOURDN @DomainID,
			@UserCN,
			@UserOURDN,
			@GUID,
			@SAMAccountName
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ADUserPutBatchByDomainIDUserCNUserOURDN]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ADUserPutBatchByDomainIDUserCNUserOURDN]
GO
CREATE PROCEDURE [dbo].[ADUserPutBatchByDomainIDUserCNUserOURDN]
AS
	DECLARE @count AS int
	SET @count = 0

	CREATE INDEX [TempADUserDomainIDUserCNUserOURDN]
		ON #ADUser (DomainID, UserCN, UserOURDN)

	BEGIN TRANSACTION
	UPDATE [dbo].[ADUser]
		SET	GUID = t.GUID,
			SAMAccountName = t.SAMAccountName
		FROM	#ADUser AS t
		WHERE	ADUser.DomainID = t.DomainID
		  AND	ADUser.UserCN = t.UserCN
		  AND	ADUser.UserOURDN = t.UserOURDN
	SET @count = @@ROWCOUNT

	INSERT [dbo].[ADUser] (
		DomainID,
		UserCN,
		UserOURDN,
		GUID,
		SAMAccountName
	)
		SELECT	DomainID,
			UserCN,
			UserOURDN,
			GUID,
			SAMAccountName
		FROM	#ADUser AS t
		WHERE NOT EXISTS(	-- Current record doesn't exist
			SELECT * FROM [dbo].[ADUser]
			WHERE	ADUser.DomainID = t.DomainID
			  AND	ADUser.UserCN = t.UserCN
			  AND	ADUser.UserOURDN = t.UserOURDN
		)
	SET @count = @count + @@ROWCOUNT
	DROP TABLE #ADUser	-- Drop the temporary table
	COMMIT WORK
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ADUserRemoveBatch]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ADUserRemoveBatch]
GO

CREATE PROCEDURE [dbo].[ADUserRemoveBatch]
AS

	CREATE INDEX [TempADUserADUserRemoveBatch]
		ON #ADUser (DomainID, UserCN, UserOURDN)	

	-- Delete records from ADUser identified by fields of [TempADUserADUserRemoveBatch]
	DELETE [dbo].[ADUser]
	WHERE EXISTS(
			SELECT * FROM #ADUser AS t
			WHERE	ADUser.DomainID = t.DomainID
			  AND	ADUser.UserCN = t.UserCN
			  AND	ADUser.UserOURDN = t.UserOURDN
		)
	DROP TABLE #ADUser      -- Drop the temporary table
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ADUserRemoveByDomainIDUserCNUserOURDN]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ADUserRemoveByDomainIDUserCNUserOURDN]
GO
CREATE PROCEDURE [dbo].[ADUserRemoveByDomainIDUserCNUserOURDN]
	@DomainID		int,
	@UserCN			nvarchar(64),
	@UserOURDN		nvarchar(384)
AS
	DELETE	[dbo].[ADUser]
	WHERE	DomainID = @DomainID
	  AND	UserCN = @UserCN
	  AND	UserOURDN = @UserOURDN
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ADUserRemoveAllByDomainID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ADUserRemoveAllByDomainID]
GO
CREATE PROCEDURE [dbo].[ADUserRemoveAllByDomainID]
	@DomainID		int
AS
	DELETE	[dbo].[ADUser]
	WHERE	DomainID = @DomainID
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ADUserRemoveAll]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ADUserRemoveAll]
GO
CREATE PROCEDURE [dbo].[ADUserRemoveAll]
	
AS
	DELETE	[dbo].[ADUser]
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ADUserReplaceSubsetByDomainID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ADUserReplaceSubsetByDomainID]
GO
-- Replace the record subset selected by (@DomainID)
-- using unique identifier (DomainID, UserCN, UserOURDN)
-- updating fields (GUID, SAMAccountName)
CREATE PROCEDURE [dbo].[ADUserReplaceSubsetByDomainID]
	@DomainID		int
AS
	DECLARE @count AS int
	SET @count = 0

	CREATE INDEX [TempADUserByDomainID]
		ON #ADUser (DomainID, UserCN, UserOURDN)

	BEGIN TRANSACTION
	DELETE [ADUser]
		WHERE	DomainID = @DomainID
		AND NOT EXISTS(		-- Replacement record doesn't exist
			SELECT * FROM #ADUser AS t
			WHERE	ADUser.DomainID = t.DomainID
			  AND	ADUser.UserCN = t.UserCN
			  AND	ADUser.UserOURDN = t.UserOURDN
		)

	UPDATE [dbo].[ADUser]
		SET	GUID = t.GUID,
			SAMAccountName = t.SAMAccountName
		FROM	#ADUser AS t
		WHERE	ADUser.DomainID = t.DomainID
		  AND	ADUser.UserCN = t.UserCN
		  AND	ADUser.UserOURDN = t.UserOURDN
	SET @count = @@ROWCOUNT

	INSERT [ADUser] (
		DomainID,
		UserCN,
		UserOURDN,
		GUID,
		SAMAccountName
	)
		SELECT	DomainID,
			UserCN,
			UserOURDN,
			GUID,
			SAMAccountName
		FROM	#ADUser AS t
		WHERE NOT EXISTS(	-- Current record doesn't exist
			SELECT * FROM [ADUser]
			WHERE	ADUser.DomainID = t.DomainID
			  AND	ADUser.UserCN = t.UserCN
			  AND	ADUser.UserOURDN = t.UserOURDN
		)
	SET @count = @count + @@ROWCOUNT
	DROP TABLE #ADUser	-- Drop the temporary table
	COMMIT WORK
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[GroupGetByGUID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[GroupGetByGUID]
GO
CREATE PROCEDURE [dbo].[GroupGetByGUID]
	@GUID			binary(16)
AS
	SELECT	GroupID,
		GUID,
		GroupCN,
		GroupOUID,
		GroupType
	FROM	[dbo].[Group]
	WHERE	GUID = @GUID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[GroupGetByID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[GroupGetByID]
GO
CREATE PROCEDURE [dbo].[GroupGetByID]
	@GroupID		int
AS
	SELECT	GroupID,
		GUID,
		GroupCN,
		GroupOUID,
		GroupType
	FROM	[dbo].[Group]
	WHERE	GroupID = @GroupID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[GroupGetByOUIDCN]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[GroupGetByOUIDCN]
GO
CREATE PROCEDURE [dbo].[GroupGetByOUIDCN]
	@GroupOUID		int,
	@GroupCN		nvarchar(64) = NULL
AS
	SELECT	GroupID,
		GUID,
		GroupCN,
		GroupOUID,
		GroupType
	FROM	[dbo].[Group]
	WHERE	GroupOUID = @GroupOUID
	  AND	(GroupCN = @GroupCN OR (GroupCN IS NULL AND @GroupCN IS NULL))
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[GroupGetAllByOUID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[GroupGetAllByOUID]
GO
CREATE PROCEDURE [dbo].[GroupGetAllByOUID]
	@GroupOUID		int
AS
	SELECT	GroupID,
		GUID,
		GroupCN,
		GroupOUID,
		GroupType
	FROM	[dbo].[Group]
	WHERE	GroupOUID = @GroupOUID
	ORDER BY GroupCN
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[GroupGetAll]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[GroupGetAll]
GO
CREATE PROCEDURE [dbo].[GroupGetAll]
AS
	SELECT	GroupID,
		GUID,
		GroupCN,
		GroupOUID,
		GroupType
	FROM	[dbo].[Group]
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[GroupAdd]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[GroupAdd]
GO
CREATE PROCEDURE [dbo].[GroupAdd]
	@GUID			binary(16),
	@GroupCN		nvarchar(64) = NULL,
	@GroupOUID		int,
	@GroupType		int = NULL
AS
	INSERT INTO  dbo.[Group] (
		GUID,
		GroupCN,
		GroupOUID,
		GroupType
	)
	VALUES (
		@GUID,
		@GroupCN,
		@GroupOUID,
		@GroupType
	)
	RETURN SCOPE_IDENTITY()
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[GroupBind]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[GroupBind]
GO
CREATE PROCEDURE [dbo].[GroupBind]
	@GUID			binary(16),
	@GroupCN		nvarchar(64) = NULL,
	@GroupOUID		int,
	@GroupType		int = NULL
AS
	DECLARE	@ID	int

	SELECT	@ID = GroupID
	FROM	[dbo].[Group]
	WHERE	GUID = @GUID

	IF @ID IS NULL
		EXEC @ID = GroupAdd @GUID,
			@GroupCN,
			@GroupOUID,
			@GroupType

	RETURN @ID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[GroupSchema]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[GroupSchema]
GO
CREATE PROCEDURE [dbo].[GroupSchema]
AS
	SELECT
	'IF OBJECT_ID(''tempdb..#Group'') IS NULL' + CAST(0x0A AS CHAR(1)) +
	'	CREATE TABLE #Group (' + CAST(0x0A AS CHAR(1)) +
	'		GroupID			int NULL,' + CAST(0x0A AS CHAR(1)) +
	'		GUID			binary(16) NOT NULL,' + CAST(0x0A AS CHAR(1)) +
	'		GroupCN			nvarchar(64) COLLATE database_default NULL,' + CAST(0x0A AS CHAR(1)) +
	'		GroupOUID		int NOT NULL,' + CAST(0x0A AS CHAR(1)) +
	'		GroupType		int NULL' + CAST(0x0A AS CHAR(1)) +
	'	)' + CAST(0x0A AS CHAR(1)) +
	'ELSE' + CAST(0x0A AS CHAR(1)) +
	'	DELETE FROM #Group' + CAST(0x0A AS CHAR(1)) +
	'' AS SQL
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[GroupTempAdd]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[GroupTempAdd]
GO
CREATE PROCEDURE dbo.[GroupTempAdd]
	@GroupID		int,
	@GUID			binary(16),
	@GroupCN		nvarchar(64) = NULL,
	@GroupOUID		int,
	@GroupType		int = NULL
AS
	INSERT INTO #Group (
		GroupID,
		GUID,
		GroupCN,
		GroupOUID,
		GroupType
	)
	VALUES (
		@GroupID,
		@GUID,
		@GroupCN,
		@GroupOUID,
		@GroupType
	)
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[GroupAddBatch]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[GroupAddBatch]
GO
CREATE PROCEDURE dbo.[GroupAddBatch]
AS
	DECLARE @count int
	INSERT dbo.[Group] (
		GUID,
		GroupCN,
		GroupOUID,
		GroupType
	)
		SELECT	GUID,
			GroupCN,
			GroupOUID,
			GroupType
		FROM #Group
	SET @count = @@ROWCOUNT
	DROP TABLE #Group	-- Drop temporary table
	RETURN @count
GO

/*
Add new Group bound to
	Organization using DomainID, RDN
	with GUID, GroupCN, GroupType
*/

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[GroupUpdateByID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[GroupUpdateByID]
GO
CREATE PROCEDURE [dbo].[GroupUpdateByID]
	@GroupID		int,
	@GUID			binary(16),
	@GroupCN		nvarchar(64) = NULL,
	@GroupOUID		int,
	@GroupType		int = NULL
AS
	DECLARE	@ID	int
	SET @ID = 0

	UPDATE	[dbo].[Group]
	SET	@ID = GroupID,
		GUID = @GUID,
		GroupCN = @GroupCN,
		GroupOUID = @GroupOUID,
		GroupType = @GroupType
	WHERE	GroupID = @GroupID
	RETURN @ID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[GroupUpdateBatchByID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[GroupUpdateBatchByID]
GO
CREATE PROCEDURE dbo.[GroupUpdateBatchByID]
AS
	DECLARE @count int

	CREATE INDEX [TempGroupID]
		ON #Group (GroupID)

	UPDATE	[dbo].[Group]
	SET	GUID = t.GUID,
		GroupCN = t.GroupCN,
		GroupOUID = t.GroupOUID,
		GroupType = t.GroupType
	FROM	#Group AS t
	WHERE	[Group].GroupID = t.GroupID
	SET @count = @@ROWCOUNT
	DROP TABLE #Group	-- Drop the temporary table
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[GroupUpdateByGUID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[GroupUpdateByGUID]
GO
CREATE PROCEDURE [dbo].[GroupUpdateByGUID]
	@GUID			binary(16),
	@GroupCN		nvarchar(64) = NULL,
	@GroupOUID		int,
	@GroupType		int = NULL
AS
	DECLARE	@ID	int
	SET @ID = 0

	UPDATE	[dbo].[Group]
	SET	@ID = GroupID,
		GroupCN = @GroupCN,
		GroupOUID = @GroupOUID,
		GroupType = @GroupType
	WHERE	GUID = @GUID
	RETURN @ID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[GroupUpdateBatchByGUID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[GroupUpdateBatchByGUID]
GO
CREATE PROCEDURE dbo.[GroupUpdateBatchByGUID]
AS
	DECLARE @count int

	CREATE INDEX [TempGroupGUID]
		ON #Group (GUID)

	UPDATE	[dbo].[Group]
	SET	GroupCN = t.GroupCN,
		GroupOUID = t.GroupOUID,
		GroupType = t.GroupType
	FROM	#Group AS t
	WHERE	[Group].GUID = t.GUID
	SET @count = @@ROWCOUNT
	DROP TABLE #Group	-- Drop the temporary table
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[GroupPutByGUID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[GroupPutByGUID]
GO
CREATE PROCEDURE [dbo].[GroupPutByGUID]
	@GUID			binary(16),
	@GroupCN		nvarchar(64) = NULL,
	@GroupOUID		int,
	@GroupType		int = NULL
AS
	DECLARE @ID	int

	SELECT	@ID = GroupID
	FROM	[Group]
	WHERE	GUID = @GUID

	IF @ID IS NULL
		EXEC @ID = GroupAdd @GUID,
			@GroupCN,
			@GroupOUID,
			@GroupType
	ELSE
		EXEC GroupUpdateByGUID @GUID,
			@GroupCN,
			@GroupOUID,
			@GroupType

	RETURN @ID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[GroupPutBatchByGUID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[GroupPutBatchByGUID]
GO
CREATE PROCEDURE [dbo].[GroupPutBatchByGUID]
AS
	DECLARE @count AS int
	SET @count = 0

	CREATE INDEX [TempGroupGUID]
		ON #Group (GUID)

	BEGIN TRANSACTION
	UPDATE [dbo].[Group]
		SET	GroupCN = t.GroupCN,
			GroupOUID = t.GroupOUID,
			GroupType = t.GroupType
		FROM	#Group AS t
		WHERE	[Group].GUID = t.GUID
	SET @count = @@ROWCOUNT

	INSERT [dbo].[Group] (
		GUID,
		GroupCN,
		GroupOUID,
		GroupType
	)
		SELECT	GUID,
			GroupCN,
			GroupOUID,
			GroupType
		FROM	#Group AS t
		WHERE NOT EXISTS(	-- Current record doesn't exist
			SELECT * FROM [dbo].[Group]
			WHERE	[Group].GUID = t.GUID
		)
	SET @count = @count + @@ROWCOUNT
	DROP TABLE #Group	-- Drop the temporary table
	COMMIT WORK
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[GroupRemoveBatch]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[GroupRemoveBatch]
GO

CREATE PROCEDURE [dbo].[GroupRemoveBatch]
AS

	CREATE INDEX [TempGroupGroupRemoveBatch]
		ON #Group (GroupID)	

	-- Delete records from Group identified by fields of [TempGroupGroupRemoveBatch]
	DELETE [dbo].[Group]
	WHERE EXISTS(
			SELECT * FROM #Group AS t
			WHERE	[Group].GroupID = t.GroupID
		)
	DROP TABLE #Group      -- Drop the temporary table
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[GroupRemoveByGUID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[GroupRemoveByGUID]
GO
CREATE PROCEDURE [dbo].[GroupRemoveByGUID]
	@GUID			binary(16)
AS
	-- Group deletes cascade to:
	--	Member by FK_Member_Group
	--	TransitiveMember by FK_TransitiveMember_Group
	--	PackageAllocation by FK_Allocation_AccessGroup
	--	Right by FK_Right_Group
	-- Group deletes may fail due to non-cascading FKs:
	--	Policy by FK_Policy_AccessGroup
	DELETE	[dbo].[Group]
	WHERE	GUID = @GUID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[GroupRemoveByID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[GroupRemoveByID]
GO
CREATE PROCEDURE [dbo].[GroupRemoveByID]
	@GroupID		int
AS
	-- Group deletes cascade to:
	--	Member by FK_Member_Group
	--	TransitiveMember by FK_TransitiveMember_Group
	--	PackageAllocation by FK_Allocation_AccessGroup
	--	Right by FK_Right_Group
	-- Group deletes may fail due to non-cascading FKs:
	--	Policy by FK_Policy_AccessGroup
	DELETE	[dbo].[Group]
	WHERE	GroupID = @GroupID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[GroupRemoveAllByOUID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[GroupRemoveAllByOUID]
GO
CREATE PROCEDURE [dbo].[GroupRemoveAllByOUID]
	@GroupOUID		int
AS
	DELETE	[dbo].[Group]
	WHERE	GroupOUID = @GroupOUID
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[GroupRemoveAll]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[GroupRemoveAll]
GO
CREATE PROCEDURE [dbo].[GroupRemoveAll]
	
AS
	DELETE	[dbo].[Group]
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[GroupReplaceSubsetByOUID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[GroupReplaceSubsetByOUID]
GO
-- Replace the record subset selected by (@GroupOUID)
-- using unique identifier (GUID)
-- updating fields (GroupCN, GroupType)
CREATE PROCEDURE [dbo].[GroupReplaceSubsetByOUID]
	@GroupOUID		int
AS
	DECLARE @count AS int
	SET @count = 0

	CREATE INDEX [TempGroupByOUID]
		ON #Group (GUID)

	BEGIN TRANSACTION
	DELETE [Group]
		WHERE	GroupOUID = @GroupOUID
		AND NOT EXISTS(		-- Replacement record doesn't exist
			SELECT * FROM #Group AS t
			WHERE	[Group].GUID = t.GUID
		)

	UPDATE [dbo].[Group]
		SET	GroupCN = t.GroupCN,
			GroupType = t.GroupType
		FROM	#Group AS t
		WHERE	[Group].GUID = t.GUID
	SET @count = @@ROWCOUNT

	INSERT [Group] (
		GUID,
		GroupCN,
		GroupOUID,
		GroupType
	)
		SELECT	GUID,
			GroupCN,
			GroupOUID,
			GroupType
		FROM	#Group AS t
		WHERE NOT EXISTS(	-- Current record doesn't exist
			SELECT * FROM [Group]
			WHERE	[Group].GUID = t.GUID
		)
	SET @count = @count + @@ROWCOUNT
	DROP TABLE #Group	-- Drop the temporary table
	COMMIT WORK
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[MemberGetByGroupIDTargetTypeIDTargetID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[MemberGetByGroupIDTargetTypeIDTargetID]
GO
CREATE PROCEDURE [dbo].[MemberGetByGroupIDTargetTypeIDTargetID]
	@GroupID		int,
	@TargetTypeID		int,
	@TargetID		int
AS
	SELECT	GroupID,
		TargetTypeID,
		TargetID,
		MemberMode
	FROM	[dbo].[Member]
	WHERE	GroupID = @GroupID
	  AND	TargetTypeID = @TargetTypeID
	  AND	TargetID = @TargetID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[MemberGetAllByGroupID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[MemberGetAllByGroupID]
GO
CREATE PROCEDURE [dbo].[MemberGetAllByGroupID]
	@GroupID		int
AS
	SELECT	GroupID,
		TargetTypeID,
		TargetID,
		MemberMode
	FROM	[dbo].[Member]
	WHERE	GroupID = @GroupID
	ORDER BY TargetTypeID, TargetID
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[MemberGetAll]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[MemberGetAll]
GO
CREATE PROCEDURE [dbo].[MemberGetAll]
AS
	SELECT	GroupID,
		TargetTypeID,
		TargetID,
		MemberMode
	FROM	[dbo].[Member]
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[MemberAdd]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[MemberAdd]
GO
CREATE PROCEDURE [dbo].[MemberAdd]
	@GroupID		int,
	@TargetTypeID		int,
	@TargetID		int,
	@MemberMode		int = 1
AS
	INSERT INTO  dbo.Member (
		GroupID,
		TargetTypeID,
		TargetID,
		MemberMode
	)
	VALUES (
		@GroupID,
		@TargetTypeID,
		@TargetID,
		@MemberMode
	)
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[MemberSchema]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[MemberSchema]
GO
CREATE PROCEDURE [dbo].[MemberSchema]
AS
	SELECT
	'IF OBJECT_ID(''tempdb..#Member'') IS NULL' + CAST(0x0A AS CHAR(1)) +
	'	CREATE TABLE #Member (' + CAST(0x0A AS CHAR(1)) +
	'		GroupID			int NOT NULL,' + CAST(0x0A AS CHAR(1)) +
	'		TargetTypeID		int NOT NULL,' + CAST(0x0A AS CHAR(1)) +
	'		TargetID		int NOT NULL,' + CAST(0x0A AS CHAR(1)) +
	'		MemberMode		int NOT NULL DEFAULT 1' + CAST(0x0A AS CHAR(1)) +
	'	)' + CAST(0x0A AS CHAR(1)) +
	'ELSE' + CAST(0x0A AS CHAR(1)) +
	'	DELETE FROM #Member' + CAST(0x0A AS CHAR(1)) +
	'' AS SQL
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[MemberTempAdd]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[MemberTempAdd]
GO
CREATE PROCEDURE dbo.[MemberTempAdd]
	@GroupID		int,
	@TargetTypeID		int,
	@TargetID		int,
	@MemberMode		int = 1
AS
	INSERT INTO #Member (
		GroupID,
		TargetTypeID,
		TargetID,
		MemberMode
	)
	VALUES (
		@GroupID,
		@TargetTypeID,
		@TargetID,
		@MemberMode
	)
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[MemberAddBatch]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[MemberAddBatch]
GO
CREATE PROCEDURE dbo.[MemberAddBatch]
AS
	DECLARE @count int
	INSERT dbo.Member (
		GroupID,
		TargetTypeID,
		TargetID,
		MemberMode
	)
		SELECT	GroupID,
			TargetTypeID,
			TargetID,
			MemberMode
		FROM #Member
	SET @count = @@ROWCOUNT
	DROP TABLE #Member	-- Drop temporary table
	RETURN @count
GO

/*
Add new Member bound to
	TargetType using TargetTypeName
	Group using GUID with GroupOUID
	with TargetID, MemberMode
*/

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[MemberUpdateByGroupIDTargetTypeIDTargetID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[MemberUpdateByGroupIDTargetTypeIDTargetID]
GO
CREATE PROCEDURE [dbo].[MemberUpdateByGroupIDTargetTypeIDTargetID]
	@GroupID		int,
	@TargetTypeID		int,
	@TargetID		int,
	@MemberMode		int = 1
AS
	UPDATE	[dbo].[Member]
	SET	MemberMode = @MemberMode
	WHERE	GroupID = @GroupID
	  AND	TargetTypeID = @TargetTypeID
	  AND	TargetID = @TargetID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[MemberUpdateBatchByGroupIDTargetTypeIDTargetID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[MemberUpdateBatchByGroupIDTargetTypeIDTargetID]
GO
CREATE PROCEDURE dbo.[MemberUpdateBatchByGroupIDTargetTypeIDTargetID]
AS
	DECLARE @count int

	CREATE INDEX [TempMemberGroupIDTargetTypeIDTargetID]
		ON #Member (GroupID, TargetTypeID, TargetID)

	UPDATE	[dbo].[Member]
	SET	MemberMode = t.MemberMode
	FROM	#Member AS t
	WHERE	Member.GroupID = t.GroupID
	  AND	Member.TargetTypeID = t.TargetTypeID
	  AND	Member.TargetID = t.TargetID
	SET @count = @@ROWCOUNT
	DROP TABLE #Member	-- Drop the temporary table
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[MemberPutByGroupIDTargetTypeIDTargetID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[MemberPutByGroupIDTargetTypeIDTargetID]
GO
CREATE PROCEDURE [dbo].[MemberPutByGroupIDTargetTypeIDTargetID]
	@GroupID		int,
	@TargetTypeID		int,
	@TargetID		int,
	@MemberMode		int = 1
AS
	IF NOT EXISTS(
		SELECT	1
		FROM	dbo.Member
		WHERE	GroupID = @GroupID
		  AND	TargetTypeID = @TargetTypeID
		  AND	TargetID = @TargetID
	)
		EXEC MemberAdd @GroupID,
			@TargetTypeID,
			@TargetID,
			@MemberMode
	ELSE
		EXEC MemberUpdateByGroupIDTargetTypeIDTargetID @GroupID,
			@TargetTypeID,
			@TargetID,
			@MemberMode
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[MemberPutBatchByGroupIDTargetTypeIDTargetID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[MemberPutBatchByGroupIDTargetTypeIDTargetID]
GO
CREATE PROCEDURE [dbo].[MemberPutBatchByGroupIDTargetTypeIDTargetID]
AS
	DECLARE @count AS int
	SET @count = 0

	CREATE INDEX [TempMemberGroupIDTargetTypeIDTargetID]
		ON #Member (GroupID, TargetTypeID, TargetID)

	BEGIN TRANSACTION
	UPDATE [dbo].[Member]
		SET	MemberMode = t.MemberMode
		FROM	#Member AS t
		WHERE	Member.GroupID = t.GroupID
		  AND	Member.TargetTypeID = t.TargetTypeID
		  AND	Member.TargetID = t.TargetID
	SET @count = @@ROWCOUNT

	INSERT [dbo].[Member] (
		GroupID,
		TargetTypeID,
		TargetID,
		MemberMode
	)
		SELECT	GroupID,
			TargetTypeID,
			TargetID,
			MemberMode
		FROM	#Member AS t
		WHERE NOT EXISTS(	-- Current record doesn't exist
			SELECT * FROM [dbo].[Member]
			WHERE	Member.GroupID = t.GroupID
			  AND	Member.TargetTypeID = t.TargetTypeID
			  AND	Member.TargetID = t.TargetID
		)
	SET @count = @count + @@ROWCOUNT
	DROP TABLE #Member	-- Drop the temporary table
	COMMIT WORK
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[MemberRemoveBatch]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[MemberRemoveBatch]
GO

CREATE PROCEDURE [dbo].[MemberRemoveBatch]
AS

	CREATE INDEX [TempMemberMemberRemoveBatch]
		ON #Member (GroupID, TargetTypeID, TargetID)	

	-- Delete records from Member identified by fields of [TempMemberMemberRemoveBatch]
	DELETE [dbo].[Member]
	WHERE EXISTS(
			SELECT * FROM #Member AS t
			WHERE	Member.GroupID = t.GroupID
			  AND	Member.TargetTypeID = t.TargetTypeID
			  AND	Member.TargetID = t.TargetID
		)
	DROP TABLE #Member      -- Drop the temporary table
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[MemberRemoveByGroupIDTargetTypeIDTargetID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[MemberRemoveByGroupIDTargetTypeIDTargetID]
GO
CREATE PROCEDURE [dbo].[MemberRemoveByGroupIDTargetTypeIDTargetID]
	@GroupID		int,
	@TargetTypeID		int,
	@TargetID		int
AS
	DELETE	[dbo].[Member]
	WHERE	GroupID = @GroupID
	  AND	TargetTypeID = @TargetTypeID
	  AND	TargetID = @TargetID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[MemberRemoveAll]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[MemberRemoveAll]
GO
CREATE PROCEDURE [dbo].[MemberRemoveAll]
	
AS
	DELETE	[dbo].[Member]
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[TransitiveMemberGetByGroupIDTargetTypeIDTargetID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[TransitiveMemberGetByGroupIDTargetTypeIDTargetID]
GO
CREATE PROCEDURE [dbo].[TransitiveMemberGetByGroupIDTargetTypeIDTargetID]
	@GroupID		int,
	@TargetTypeID		int,
	@TargetID		int
AS
	SELECT	GroupID,
		TargetTypeID,
		TargetID,
		MemberMode
	FROM	[dbo].[TransitiveMember]
	WHERE	GroupID = @GroupID
	  AND	TargetTypeID = @TargetTypeID
	  AND	TargetID = @TargetID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[TransitiveMemberGetAll]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[TransitiveMemberGetAll]
GO
CREATE PROCEDURE [dbo].[TransitiveMemberGetAll]
AS
	SELECT	GroupID,
		TargetTypeID,
		TargetID,
		MemberMode
	FROM	[dbo].[TransitiveMember]
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[TransitiveMemberAdd]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[TransitiveMemberAdd]
GO
CREATE PROCEDURE [dbo].[TransitiveMemberAdd]
	@GroupID		int,
	@TargetTypeID		int,
	@TargetID		int,
	@MemberMode		int = 1
AS
	INSERT INTO  dbo.TransitiveMember (
		GroupID,
		TargetTypeID,
		TargetID,
		MemberMode
	)
	VALUES (
		@GroupID,
		@TargetTypeID,
		@TargetID,
		@MemberMode
	)
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[TransitiveMemberSchema]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[TransitiveMemberSchema]
GO
CREATE PROCEDURE [dbo].[TransitiveMemberSchema]
AS
	SELECT
	'IF OBJECT_ID(''tempdb..#TransitiveMember'') IS NULL' + CAST(0x0A AS CHAR(1)) +
	'	CREATE TABLE #TransitiveMember (' + CAST(0x0A AS CHAR(1)) +
	'		GroupID			int NOT NULL,' + CAST(0x0A AS CHAR(1)) +
	'		TargetTypeID		int NOT NULL,' + CAST(0x0A AS CHAR(1)) +
	'		TargetID		int NOT NULL,' + CAST(0x0A AS CHAR(1)) +
	'		MemberMode		int NOT NULL DEFAULT 1' + CAST(0x0A AS CHAR(1)) +
	'	)' + CAST(0x0A AS CHAR(1)) +
	'ELSE' + CAST(0x0A AS CHAR(1)) +
	'	DELETE FROM #TransitiveMember' + CAST(0x0A AS CHAR(1)) +
	'' AS SQL
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[TransitiveMemberTempAdd]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[TransitiveMemberTempAdd]
GO
CREATE PROCEDURE dbo.[TransitiveMemberTempAdd]
	@GroupID		int,
	@TargetTypeID		int,
	@TargetID		int,
	@MemberMode		int = 1
AS
	INSERT INTO #TransitiveMember (
		GroupID,
		TargetTypeID,
		TargetID,
		MemberMode
	)
	VALUES (
		@GroupID,
		@TargetTypeID,
		@TargetID,
		@MemberMode
	)
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[TransitiveMemberAddBatch]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[TransitiveMemberAddBatch]
GO
CREATE PROCEDURE dbo.[TransitiveMemberAddBatch]
AS
	DECLARE @count int
	INSERT dbo.TransitiveMember (
		GroupID,
		TargetTypeID,
		TargetID,
		MemberMode
	)
		SELECT	GroupID,
			TargetTypeID,
			TargetID,
			MemberMode
		FROM #TransitiveMember
	SET @count = @@ROWCOUNT
	DROP TABLE #TransitiveMember	-- Drop temporary table
	RETURN @count
GO

/*
Add new TransitiveMember bound to
	TargetType using TargetTypeName
	Group using GUID with GroupOUID
	with TargetID, MemberMode
*/

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[TransitiveMemberUpdateByGroupIDTargetTypeIDTargetID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[TransitiveMemberUpdateByGroupIDTargetTypeIDTargetID]
GO
CREATE PROCEDURE [dbo].[TransitiveMemberUpdateByGroupIDTargetTypeIDTargetID]
	@GroupID		int,
	@TargetTypeID		int,
	@TargetID		int,
	@MemberMode		int = 1
AS
	UPDATE	[dbo].[TransitiveMember]
	SET	MemberMode = @MemberMode
	WHERE	GroupID = @GroupID
	  AND	TargetTypeID = @TargetTypeID
	  AND	TargetID = @TargetID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[TransitiveMemberUpdateBatchByGroupIDTargetTypeIDTargetID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[TransitiveMemberUpdateBatchByGroupIDTargetTypeIDTargetID]
GO
CREATE PROCEDURE dbo.[TransitiveMemberUpdateBatchByGroupIDTargetTypeIDTargetID]
AS
	DECLARE @count int

	CREATE INDEX [TempTransitiveMemberGroupIDTargetTypeIDTargetID]
		ON #TransitiveMember (GroupID, TargetTypeID, TargetID)

	UPDATE	[dbo].[TransitiveMember]
	SET	MemberMode = t.MemberMode
	FROM	#TransitiveMember AS t
	WHERE	TransitiveMember.GroupID = t.GroupID
	  AND	TransitiveMember.TargetTypeID = t.TargetTypeID
	  AND	TransitiveMember.TargetID = t.TargetID
	SET @count = @@ROWCOUNT
	DROP TABLE #TransitiveMember	-- Drop the temporary table
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[TransitiveMemberPutByGroupIDTargetTypeIDTargetID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[TransitiveMemberPutByGroupIDTargetTypeIDTargetID]
GO
CREATE PROCEDURE [dbo].[TransitiveMemberPutByGroupIDTargetTypeIDTargetID]
	@GroupID		int,
	@TargetTypeID		int,
	@TargetID		int,
	@MemberMode		int = 1
AS
	IF NOT EXISTS(
		SELECT	1
		FROM	dbo.TransitiveMember
		WHERE	GroupID = @GroupID
		  AND	TargetTypeID = @TargetTypeID
		  AND	TargetID = @TargetID
	)
		EXEC TransitiveMemberAdd @GroupID,
			@TargetTypeID,
			@TargetID,
			@MemberMode
	ELSE
		EXEC TransitiveMemberUpdateByGroupIDTargetTypeIDTargetID @GroupID,
			@TargetTypeID,
			@TargetID,
			@MemberMode
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[TransitiveMemberPutBatchByGroupIDTargetTypeIDTargetID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[TransitiveMemberPutBatchByGroupIDTargetTypeIDTargetID]
GO
CREATE PROCEDURE [dbo].[TransitiveMemberPutBatchByGroupIDTargetTypeIDTargetID]
AS
	DECLARE @count AS int
	SET @count = 0

	CREATE INDEX [TempTransitiveMemberGroupIDTargetTypeIDTargetID]
		ON #TransitiveMember (GroupID, TargetTypeID, TargetID)

	BEGIN TRANSACTION
	UPDATE [dbo].[TransitiveMember]
		SET	MemberMode = t.MemberMode
		FROM	#TransitiveMember AS t
		WHERE	TransitiveMember.GroupID = t.GroupID
		  AND	TransitiveMember.TargetTypeID = t.TargetTypeID
		  AND	TransitiveMember.TargetID = t.TargetID
	SET @count = @@ROWCOUNT

	INSERT [dbo].[TransitiveMember] (
		GroupID,
		TargetTypeID,
		TargetID,
		MemberMode
	)
		SELECT	GroupID,
			TargetTypeID,
			TargetID,
			MemberMode
		FROM	#TransitiveMember AS t
		WHERE NOT EXISTS(	-- Current record doesn't exist
			SELECT * FROM [dbo].[TransitiveMember]
			WHERE	TransitiveMember.GroupID = t.GroupID
			  AND	TransitiveMember.TargetTypeID = t.TargetTypeID
			  AND	TransitiveMember.TargetID = t.TargetID
		)
	SET @count = @count + @@ROWCOUNT
	DROP TABLE #TransitiveMember	-- Drop the temporary table
	COMMIT WORK
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[TransitiveMemberRemoveBatch]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[TransitiveMemberRemoveBatch]
GO

CREATE PROCEDURE [dbo].[TransitiveMemberRemoveBatch]
AS

	CREATE INDEX [TempTransitiveMemberTransitiveMemberRemoveBatch]
		ON #TransitiveMember (GroupID, TargetTypeID, TargetID)	

	-- Delete records from TransitiveMember identified by fields of [TempTransitiveMemberTransitiveMemberRemoveBatch]
	DELETE [dbo].[TransitiveMember]
	WHERE EXISTS(
			SELECT * FROM #TransitiveMember AS t
			WHERE	TransitiveMember.GroupID = t.GroupID
			  AND	TransitiveMember.TargetTypeID = t.TargetTypeID
			  AND	TransitiveMember.TargetID = t.TargetID
		)
	DROP TABLE #TransitiveMember      -- Drop the temporary table
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[TransitiveMemberRemoveByGroupIDTargetTypeIDTargetID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[TransitiveMemberRemoveByGroupIDTargetTypeIDTargetID]
GO
CREATE PROCEDURE [dbo].[TransitiveMemberRemoveByGroupIDTargetTypeIDTargetID]
	@GroupID		int,
	@TargetTypeID		int,
	@TargetID		int
AS
	DELETE	[dbo].[TransitiveMember]
	WHERE	GroupID = @GroupID
	  AND	TargetTypeID = @TargetTypeID
	  AND	TargetID = @TargetID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[TransitiveMemberRemoveAll]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[TransitiveMemberRemoveAll]
GO
CREATE PROCEDURE [dbo].[TransitiveMemberRemoveAll]
	
AS
	DELETE	[dbo].[TransitiveMember]
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[PackageFamilyGetByID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[PackageFamilyGetByID]
GO
CREATE PROCEDURE [dbo].[PackageFamilyGetByID]
	@PackageFamilyID	int
AS
	SELECT	PackageFamilyID,
		PackageName
	FROM	[dbo].[PackageFamily]
	WHERE	PackageFamilyID = @PackageFamilyID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[PackageFamilyGetByPackageName]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[PackageFamilyGetByPackageName]
GO
CREATE PROCEDURE [dbo].[PackageFamilyGetByPackageName]
	@PackageName		nvarchar(64)
AS
	SELECT	PackageFamilyID,
		PackageName
	FROM	[dbo].[PackageFamily]
	WHERE	PackageName = @PackageName
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[PackageFamilyGetAll]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[PackageFamilyGetAll]
GO
CREATE PROCEDURE [dbo].[PackageFamilyGetAll]
AS
	SELECT	PackageFamilyID,
		PackageName
	FROM	[dbo].[PackageFamily]
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[PackageFamilyAdd]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[PackageFamilyAdd]
GO
CREATE PROCEDURE [dbo].[PackageFamilyAdd]
	@PackageName		nvarchar(64)
AS
	INSERT INTO  dbo.PackageFamily (
		PackageName
	)
	VALUES (
		@PackageName
	)
	RETURN SCOPE_IDENTITY()
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[PackageFamilyBind]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[PackageFamilyBind]
GO
CREATE PROCEDURE [dbo].[PackageFamilyBind]
	@PackageName		nvarchar(64)
AS
	DECLARE	@ID	int

	SELECT	@ID = PackageFamilyID
	FROM	[dbo].[PackageFamily]
	WHERE	PackageName = @PackageName

	IF @ID IS NULL
		EXEC @ID = PackageFamilyAdd @PackageName

	RETURN @ID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[PackageFamilySchema]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[PackageFamilySchema]
GO
CREATE PROCEDURE [dbo].[PackageFamilySchema]
AS
	SELECT
	'IF OBJECT_ID(''tempdb..#PackageFamily'') IS NULL' + CAST(0x0A AS CHAR(1)) +
	'	CREATE TABLE #PackageFamily (' + CAST(0x0A AS CHAR(1)) +
	'		PackageFamilyID		int NULL,' + CAST(0x0A AS CHAR(1)) +
	'		PackageName		nvarchar(64) COLLATE database_default NOT NULL' + CAST(0x0A AS CHAR(1)) +
	'	)' + CAST(0x0A AS CHAR(1)) +
	'ELSE' + CAST(0x0A AS CHAR(1)) +
	'	DELETE FROM #PackageFamily' + CAST(0x0A AS CHAR(1)) +
	'' AS SQL
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[PackageFamilyTempAdd]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[PackageFamilyTempAdd]
GO
CREATE PROCEDURE dbo.[PackageFamilyTempAdd]
	@PackageFamilyID	int,
	@PackageName		nvarchar(64)
AS
	INSERT INTO #PackageFamily (
		PackageFamilyID,
		PackageName
	)
	VALUES (
		@PackageFamilyID,
		@PackageName
	)
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[PackageFamilyAddBatch]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[PackageFamilyAddBatch]
GO
CREATE PROCEDURE dbo.[PackageFamilyAddBatch]
AS
	DECLARE @count int
	INSERT dbo.PackageFamily (
		PackageName
	)
		SELECT	PackageName
		FROM #PackageFamily
	SET @count = @@ROWCOUNT
	DROP TABLE #PackageFamily	-- Drop temporary table
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[PackageFamilyUpdateByID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[PackageFamilyUpdateByID]
GO
CREATE PROCEDURE [dbo].[PackageFamilyUpdateByID]
	@PackageFamilyID	int,
	@PackageName		nvarchar(64)
AS
	DECLARE	@ID	int
	SET @ID = 0

	UPDATE	[dbo].[PackageFamily]
	SET	@ID = PackageFamilyID,
		PackageName = @PackageName
	WHERE	PackageFamilyID = @PackageFamilyID
	RETURN @ID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[PackageFamilyUpdateBatchByID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[PackageFamilyUpdateBatchByID]
GO
CREATE PROCEDURE dbo.[PackageFamilyUpdateBatchByID]
AS
	DECLARE @count int

	CREATE INDEX [TempPackageFamilyID]
		ON #PackageFamily (PackageFamilyID)

	UPDATE	[dbo].[PackageFamily]
	SET	PackageName = t.PackageName
	FROM	#PackageFamily AS t
	WHERE	PackageFamily.PackageFamilyID = t.PackageFamilyID
	SET @count = @@ROWCOUNT
	DROP TABLE #PackageFamily	-- Drop the temporary table
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[PackageFamilyPutByPackageName]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[PackageFamilyPutByPackageName]
GO
CREATE PROCEDURE [dbo].[PackageFamilyPutByPackageName]
	@PackageName		nvarchar(64)
AS
	DECLARE @ID	int

	SELECT	@ID = PackageFamilyID
	FROM	PackageFamily
	WHERE	PackageName = @PackageName

	IF @ID IS NULL
		EXEC @ID = PackageFamilyAdd @PackageName

	RETURN @ID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[PackageFamilyPutBatchByPackageName]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[PackageFamilyPutBatchByPackageName]
GO
CREATE PROCEDURE [dbo].[PackageFamilyPutBatchByPackageName]
AS
	DECLARE @count AS int
	SET @count = 0

	CREATE INDEX [TempPackageFamilyPackageName]
		ON #PackageFamily (PackageName)

	BEGIN TRANSACTION

	INSERT [dbo].[PackageFamily] (
		PackageName
	)
		SELECT	PackageName
		FROM	#PackageFamily AS t
		WHERE NOT EXISTS(	-- Current record doesn't exist
			SELECT * FROM [dbo].[PackageFamily]
			WHERE	PackageFamily.PackageName = t.PackageName
		)
	SET @count = @count + @@ROWCOUNT
	DROP TABLE #PackageFamily	-- Drop the temporary table
	COMMIT WORK
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[PackageFamilyRemoveBatch]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[PackageFamilyRemoveBatch]
GO

CREATE PROCEDURE [dbo].[PackageFamilyRemoveBatch]
AS

	CREATE INDEX [TempPackageFamilyPackageFamilyRemoveBatch]
		ON #PackageFamily (PackageFamilyID)	

	-- Delete records from PackageFamily identified by fields of [TempPackageFamilyPackageFamilyRemoveBatch]
	DELETE [dbo].[PackageFamily]
	WHERE EXISTS(
			SELECT * FROM #PackageFamily AS t
			WHERE	PackageFamily.PackageFamilyID = t.PackageFamilyID
		)
	DROP TABLE #PackageFamily      -- Drop the temporary table
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[PackageFamilyRemoveByID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[PackageFamilyRemoveByID]
GO
CREATE PROCEDURE [dbo].[PackageFamilyRemoveByID]
	@PackageFamilyID	int
AS
	-- PackageFamily deletes cascade to:
	--	PackageVersion by FK_PackageVersion_PackageFamily
	--		PackageVersionInState by FK_PackageVersionInState_PackageVersion
	--		PackageProvides by FK_PackageProvides_PackageVersion
	--		PackageRequires by FK_PackageRequires_PackageVersion
	--		MediaContainsPackageVersion by FK_MCPV_PackageVersion
	--		PackageVersionLocale by FK_PackageVersionLocale_PackageVersion
	--		PackageVersionArchitecture by FK_PackageVersionArchitecture_PackageVersion
	--		PackageVersionEnvironment by FK_PackageVersionEnvironment_PackageVersion
	--		Installation by FK_Installation_PackageVersion
	--		InstallationHistory by FK_InstallationHistory_PackageVersion
	-- PackageFamily deletes may fail due to non-cascading FKs:
	--	(through PackageVersion by FK_PackageVersion_PackageFamily)
	--		DistributedPackage by FK_DistributedPackage_Confirmed
	--		DistributedPackage by FK_DistributedPackage_Requested
	--	PackageProvides by FK_PackageProvides_PackageFamily
	DELETE	[dbo].[PackageFamily]
	WHERE	PackageFamilyID = @PackageFamilyID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[PackageFamilyRemoveByPackageName]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[PackageFamilyRemoveByPackageName]
GO
CREATE PROCEDURE [dbo].[PackageFamilyRemoveByPackageName]
	@PackageName		nvarchar(64)
AS
	-- PackageFamily deletes cascade to:
	--	PackageVersion by FK_PackageVersion_PackageFamily
	--		PackageVersionInState by FK_PackageVersionInState_PackageVersion
	--		PackageProvides by FK_PackageProvides_PackageVersion
	--		PackageRequires by FK_PackageRequires_PackageVersion
	--		MediaContainsPackageVersion by FK_MCPV_PackageVersion
	--		PackageVersionLocale by FK_PackageVersionLocale_PackageVersion
	--		PackageVersionArchitecture by FK_PackageVersionArchitecture_PackageVersion
	--		PackageVersionEnvironment by FK_PackageVersionEnvironment_PackageVersion
	--		Installation by FK_Installation_PackageVersion
	--		InstallationHistory by FK_InstallationHistory_PackageVersion
	-- PackageFamily deletes may fail due to non-cascading FKs:
	--	(through PackageVersion by FK_PackageVersion_PackageFamily)
	--		DistributedPackage by FK_DistributedPackage_Confirmed
	--		DistributedPackage by FK_DistributedPackage_Requested
	--	PackageProvides by FK_PackageProvides_PackageFamily
	DELETE	[dbo].[PackageFamily]
	WHERE	PackageName = @PackageName
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[PackageFamilyRemoveAll]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[PackageFamilyRemoveAll]
GO
CREATE PROCEDURE [dbo].[PackageFamilyRemoveAll]
	
AS
	DELETE	[dbo].[PackageFamily]
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[PackageStateGetByID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[PackageStateGetByID]
GO
CREATE PROCEDURE [dbo].[PackageStateGetByID]
	@PackageStateID		int
AS
	SELECT	PackageStateID,
		[Name],
		CanAddToPolicy
	FROM	[dbo].[PackageState]
	WHERE	PackageStateID = @PackageStateID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[PackageStateGetByName]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[PackageStateGetByName]
GO
CREATE PROCEDURE [dbo].[PackageStateGetByName]
	@Name			nvarchar(64)
AS
	SELECT	PackageStateID,
		[Name],
		CanAddToPolicy
	FROM	[dbo].[PackageState]
	WHERE	[Name] = @Name
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[PackageStateGetAll]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[PackageStateGetAll]
GO
CREATE PROCEDURE [dbo].[PackageStateGetAll]
AS
	SELECT	PackageStateID,
		[Name],
		CanAddToPolicy
	FROM	[dbo].[PackageState]
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[PackageStateBind]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[PackageStateBind]
GO
CREATE PROCEDURE [dbo].[PackageStateBind]
	@Name			nvarchar(64),
	@CanAddToPolicy		bit
AS
	DECLARE	@ID	int

	SELECT	@ID = PackageStateID
	FROM	[dbo].[PackageState]
	WHERE	[Name] = @Name

	RETURN @ID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[PackageVersionInStateGetByPackageVersionIDPackageStateIDUserNameChanged]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[PackageVersionInStateGetByPackageVersionIDPackageStateIDUserNameChanged]
GO
CREATE PROCEDURE [dbo].[PackageVersionInStateGetByPackageVersionIDPackageStateIDUserNameChanged]
	@PackageVersionID	int,
	@PackageStateID		int,
	@UserName		nvarchar(64),
	@Changed		datetime
AS
	SELECT	PackageVersionID,
		PackageStateID,
		UserName,
		Changed,
		Comments
	FROM	[dbo].[PackageVersionInState]
	WHERE	PackageVersionID = @PackageVersionID
	  AND	PackageStateID = @PackageStateID
	  AND	UserName = @UserName
	  AND	Changed = @Changed
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[PackageVersionInStateGetAllByPackageVersionIDPackageStateIDUserName]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[PackageVersionInStateGetAllByPackageVersionIDPackageStateIDUserName]
GO
CREATE PROCEDURE [dbo].[PackageVersionInStateGetAllByPackageVersionIDPackageStateIDUserName]
	@PackageVersionID	int,
	@PackageStateID		int,
	@UserName		nvarchar(64)
AS
	SELECT	PackageVersionID,
		PackageStateID,
		UserName,
		Changed,
		Comments
	FROM	[dbo].[PackageVersionInState]
	WHERE	PackageVersionID = @PackageVersionID
	  AND	PackageStateID = @PackageStateID
	  AND	UserName = @UserName
	ORDER BY Changed
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[PackageVersionInStateGetAllByPackageVersionIDPackageStateID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[PackageVersionInStateGetAllByPackageVersionIDPackageStateID]
GO
CREATE PROCEDURE [dbo].[PackageVersionInStateGetAllByPackageVersionIDPackageStateID]
	@PackageVersionID	int,
	@PackageStateID		int
AS
	SELECT	PackageVersionID,
		PackageStateID,
		UserName,
		Changed,
		Comments
	FROM	[dbo].[PackageVersionInState]
	WHERE	PackageVersionID = @PackageVersionID
	  AND	PackageStateID = @PackageStateID
	ORDER BY UserName, Changed
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[PackageVersionInStateGetAllByPackageVersionIDChanged]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[PackageVersionInStateGetAllByPackageVersionIDChanged]
GO
CREATE PROCEDURE [dbo].[PackageVersionInStateGetAllByPackageVersionIDChanged]
	@PackageVersionID	int,
	@Changed		datetime
AS
	SELECT	PackageVersionID,
		PackageStateID,
		UserName,
		Changed,
		Comments
	FROM	[dbo].[PackageVersionInState]
	WHERE	PackageVersionID = @PackageVersionID
	  AND	Changed = @Changed
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[PackageVersionInStateGetAllByPackageVersionID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[PackageVersionInStateGetAllByPackageVersionID]
GO
CREATE PROCEDURE [dbo].[PackageVersionInStateGetAllByPackageVersionID]
	@PackageVersionID	int
AS
	SELECT	PackageVersionID,
		PackageStateID,
		UserName,
		Changed,
		Comments
	FROM	[dbo].[PackageVersionInState]
	WHERE	PackageVersionID = @PackageVersionID
	ORDER BY Changed
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[PackageVersionInStateGetAll]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[PackageVersionInStateGetAll]
GO
CREATE PROCEDURE [dbo].[PackageVersionInStateGetAll]
AS
	SELECT	PackageVersionID,
		PackageStateID,
		UserName,
		Changed,
		Comments
	FROM	[dbo].[PackageVersionInState]
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[PackageVersionInStateAdd]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[PackageVersionInStateAdd]
GO
CREATE PROCEDURE [dbo].[PackageVersionInStateAdd]
	@PackageVersionID	int,
	@PackageStateID		int,
	@UserName		nvarchar(64),
	@Changed		datetime,
	@Comments		nvarchar(256)
AS
	INSERT INTO  dbo.PackageVersionInState (
		PackageVersionID,
		PackageStateID,
		UserName,
		Changed,
		Comments
	)
	VALUES (
		@PackageVersionID,
		@PackageStateID,
		@UserName,
		@Changed,
		@Comments
	)
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[PackageVersionInStateSchema]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[PackageVersionInStateSchema]
GO
CREATE PROCEDURE [dbo].[PackageVersionInStateSchema]
AS
	SELECT
	'IF OBJECT_ID(''tempdb..#PackageVersionInState'') IS NULL' + CAST(0x0A AS CHAR(1)) +
	'	CREATE TABLE #PackageVersionInState (' + CAST(0x0A AS CHAR(1)) +
	'		PackageVersionID	int NOT NULL,' + CAST(0x0A AS CHAR(1)) +
	'		PackageStateID		int NOT NULL,' + CAST(0x0A AS CHAR(1)) +
	'		UserName		nvarchar(64) COLLATE database_default NOT NULL,' + CAST(0x0A AS CHAR(1)) +
	'		Changed			datetime NOT NULL,' + CAST(0x0A AS CHAR(1)) +
	'		Comments		nvarchar(256) COLLATE database_default NOT NULL' + CAST(0x0A AS CHAR(1)) +
	'	)' + CAST(0x0A AS CHAR(1)) +
	'ELSE' + CAST(0x0A AS CHAR(1)) +
	'	DELETE FROM #PackageVersionInState' + CAST(0x0A AS CHAR(1)) +
	'' AS SQL
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[PackageVersionInStateTempAdd]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[PackageVersionInStateTempAdd]
GO
CREATE PROCEDURE dbo.[PackageVersionInStateTempAdd]
	@PackageVersionID	int,
	@PackageStateID		int,
	@UserName		nvarchar(64),
	@Changed		datetime,
	@Comments		nvarchar(256)
AS
	INSERT INTO #PackageVersionInState (
		PackageVersionID,
		PackageStateID,
		UserName,
		Changed,
		Comments
	)
	VALUES (
		@PackageVersionID,
		@PackageStateID,
		@UserName,
		@Changed,
		@Comments
	)
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[PackageVersionInStateAddBatch]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[PackageVersionInStateAddBatch]
GO
CREATE PROCEDURE dbo.[PackageVersionInStateAddBatch]
AS
	DECLARE @count int
	INSERT dbo.PackageVersionInState (
		PackageVersionID,
		PackageStateID,
		UserName,
		Changed,
		Comments
	)
		SELECT	PackageVersionID,
			PackageStateID,
			UserName,
			Changed,
			Comments
		FROM #PackageVersionInState
	SET @count = @@ROWCOUNT
	DROP TABLE #PackageVersionInState	-- Drop temporary table
	RETURN @count
GO

/*
Add new PackageVersionInState bound to
	PackageVersion using PackagePathID, Version, Update with PackageFamilyID
	PackageState using Name
	with UserName, Changed, Comments
*/

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[PackageVersionInStateUpdateByPackageVersionIDPackageStateIDUserNameChanged]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[PackageVersionInStateUpdateByPackageVersionIDPackageStateIDUserNameChanged]
GO
CREATE PROCEDURE [dbo].[PackageVersionInStateUpdateByPackageVersionIDPackageStateIDUserNameChanged]
	@PackageVersionID	int,
	@PackageStateID		int,
	@UserName		nvarchar(64),
	@Changed		datetime,
	@Comments		nvarchar(256)
AS
	UPDATE	[dbo].[PackageVersionInState]
	SET	Comments = @Comments
	WHERE	PackageVersionID = @PackageVersionID
	  AND	PackageStateID = @PackageStateID
	  AND	UserName = @UserName
	  AND	Changed = @Changed
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[PackageVersionInStateUpdateBatchByPackageVersionIDPackageStateIDUserNameChanged]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[PackageVersionInStateUpdateBatchByPackageVersionIDPackageStateIDUserNameChanged]
GO
CREATE PROCEDURE dbo.[PackageVersionInStateUpdateBatchByPackageVersionIDPackageStateIDUserNameChanged]
AS
	DECLARE @count int

	CREATE INDEX [TempPackageVersionInStatePackageVersionIDPackageStateIDUserNameChanged]
		ON #PackageVersionInState (PackageVersionID, PackageStateID, UserName, Changed)

	UPDATE	[dbo].[PackageVersionInState]
	SET	Comments = t.Comments
	FROM	#PackageVersionInState AS t
	WHERE	PackageVersionInState.PackageVersionID = t.PackageVersionID
	  AND	PackageVersionInState.PackageStateID = t.PackageStateID
	  AND	PackageVersionInState.UserName = t.UserName
	  AND	PackageVersionInState.Changed = t.Changed
	SET @count = @@ROWCOUNT
	DROP TABLE #PackageVersionInState	-- Drop the temporary table
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[PackageVersionInStatePutByPackageVersionIDPackageStateIDUserNameChanged]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[PackageVersionInStatePutByPackageVersionIDPackageStateIDUserNameChanged]
GO
CREATE PROCEDURE [dbo].[PackageVersionInStatePutByPackageVersionIDPackageStateIDUserNameChanged]
	@PackageVersionID	int,
	@PackageStateID		int,
	@UserName		nvarchar(64),
	@Changed		datetime,
	@Comments		nvarchar(256)
AS
	IF NOT EXISTS(
		SELECT	1
		FROM	dbo.PackageVersionInState
		WHERE	PackageVersionID = @PackageVersionID
		  AND	PackageStateID = @PackageStateID
		  AND	UserName = @UserName
		  AND	Changed = @Changed
	)
		EXEC PackageVersionInStateAdd @PackageVersionID,
			@PackageStateID,
			@UserName,
			@Changed,
			@Comments
	ELSE
		EXEC PackageVersionInStateUpdateByPackageVersionIDPackageStateIDUserNameChanged @PackageVersionID,
			@PackageStateID,
			@UserName,
			@Changed,
			@Comments
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[PackageVersionInStatePutBatchByPackageVersionIDPackageStateIDUserNameChanged]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[PackageVersionInStatePutBatchByPackageVersionIDPackageStateIDUserNameChanged]
GO
CREATE PROCEDURE [dbo].[PackageVersionInStatePutBatchByPackageVersionIDPackageStateIDUserNameChanged]
AS
	DECLARE @count AS int
	SET @count = 0

	CREATE INDEX [TempPackageVersionInStatePackageVersionIDPackageStateIDUserNameChanged]
		ON #PackageVersionInState (PackageVersionID, PackageStateID, UserName, Changed)

	BEGIN TRANSACTION
	UPDATE [dbo].[PackageVersionInState]
		SET	Comments = t.Comments
		FROM	#PackageVersionInState AS t
		WHERE	PackageVersionInState.PackageVersionID = t.PackageVersionID
		  AND	PackageVersionInState.PackageStateID = t.PackageStateID
		  AND	PackageVersionInState.UserName = t.UserName
		  AND	PackageVersionInState.Changed = t.Changed
	SET @count = @@ROWCOUNT

	INSERT [dbo].[PackageVersionInState] (
		PackageVersionID,
		PackageStateID,
		UserName,
		Changed,
		Comments
	)
		SELECT	PackageVersionID,
			PackageStateID,
			UserName,
			Changed,
			Comments
		FROM	#PackageVersionInState AS t
		WHERE NOT EXISTS(	-- Current record doesn't exist
			SELECT * FROM [dbo].[PackageVersionInState]
			WHERE	PackageVersionInState.PackageVersionID = t.PackageVersionID
			  AND	PackageVersionInState.PackageStateID = t.PackageStateID
			  AND	PackageVersionInState.UserName = t.UserName
			  AND	PackageVersionInState.Changed = t.Changed
		)
	SET @count = @count + @@ROWCOUNT
	DROP TABLE #PackageVersionInState	-- Drop the temporary table
	COMMIT WORK
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[PackageVersionInStateRemoveBatch]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[PackageVersionInStateRemoveBatch]
GO

CREATE PROCEDURE [dbo].[PackageVersionInStateRemoveBatch]
AS

	CREATE INDEX [TempPackageVersionInStatePackageVersionInStateRemoveBatch]
		ON #PackageVersionInState (PackageVersionID, PackageStateID, UserName, Changed)	

	-- Delete records from PackageVersionInState identified by fields of [TempPackageVersionInStatePackageVersionInStateRemoveBatch]
	DELETE [dbo].[PackageVersionInState]
	WHERE EXISTS(
			SELECT * FROM #PackageVersionInState AS t
			WHERE	PackageVersionInState.PackageVersionID = t.PackageVersionID
			  AND	PackageVersionInState.PackageStateID = t.PackageStateID
			  AND	PackageVersionInState.UserName = t.UserName
			  AND	PackageVersionInState.Changed = t.Changed
		)
	DROP TABLE #PackageVersionInState      -- Drop the temporary table
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[PackageVersionInStateRemoveByPackageVersionIDPackageStateIDUserNameChanged]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[PackageVersionInStateRemoveByPackageVersionIDPackageStateIDUserNameChanged]
GO
CREATE PROCEDURE [dbo].[PackageVersionInStateRemoveByPackageVersionIDPackageStateIDUserNameChanged]
	@PackageVersionID	int,
	@PackageStateID		int,
	@UserName		nvarchar(64),
	@Changed		datetime
AS
	DELETE	[dbo].[PackageVersionInState]
	WHERE	PackageVersionID = @PackageVersionID
	  AND	PackageStateID = @PackageStateID
	  AND	UserName = @UserName
	  AND	Changed = @Changed
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[PackageVersionInStateRemoveAllByPackageVersionIDPackageStateIDUserName]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[PackageVersionInStateRemoveAllByPackageVersionIDPackageStateIDUserName]
GO
CREATE PROCEDURE [dbo].[PackageVersionInStateRemoveAllByPackageVersionIDPackageStateIDUserName]
	@PackageVersionID	int,
	@PackageStateID		int,
	@UserName		nvarchar(64)
AS
	DELETE	[dbo].[PackageVersionInState]
	WHERE	PackageVersionID = @PackageVersionID
	  AND	PackageStateID = @PackageStateID
	  AND	UserName = @UserName
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[PackageVersionInStateRemoveAllByPackageVersionIDPackageStateID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[PackageVersionInStateRemoveAllByPackageVersionIDPackageStateID]
GO
CREATE PROCEDURE [dbo].[PackageVersionInStateRemoveAllByPackageVersionIDPackageStateID]
	@PackageVersionID	int,
	@PackageStateID		int
AS
	DELETE	[dbo].[PackageVersionInState]
	WHERE	PackageVersionID = @PackageVersionID
	  AND	PackageStateID = @PackageStateID
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[PackageVersionInStateRemoveAll]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[PackageVersionInStateRemoveAll]
GO
CREATE PROCEDURE [dbo].[PackageVersionInStateRemoveAll]
	
AS
	DELETE	[dbo].[PackageVersionInState]
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[PackagePathTypeGetByID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[PackagePathTypeGetByID]
GO
CREATE PROCEDURE [dbo].[PackagePathTypeGetByID]
	@PackagePathTypeID	int
AS
	SELECT	PackagePathTypeID,
		Description
	FROM	[dbo].[PackagePathType]
	WHERE	PackagePathTypeID = @PackagePathTypeID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[PackagePathTypeGetAllByDescription]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[PackagePathTypeGetAllByDescription]
GO
CREATE PROCEDURE [dbo].[PackagePathTypeGetAllByDescription]
	@Description		nvarchar(128)
AS
	SELECT	PackagePathTypeID,
		Description
	FROM	[dbo].[PackagePathType]
	WHERE	Description = @Description
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[PackagePathTypeGetAll]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[PackagePathTypeGetAll]
GO
CREATE PROCEDURE [dbo].[PackagePathTypeGetAll]
AS
	SELECT	PackagePathTypeID,
		Description
	FROM	[dbo].[PackagePathType]
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[PackagePathGetByID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[PackagePathGetByID]
GO
CREATE PROCEDURE [dbo].[PackagePathGetByID]
	@PackagePathID		int
AS
	SELECT	PackagePathID,
		PackageFullName,
		ParentPathID,
		PackagePathTypeID
	FROM	[dbo].[PackagePath]
	WHERE	PackagePathID = @PackagePathID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[PackagePathGetByPackageFullName]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[PackagePathGetByPackageFullName]
GO
CREATE PROCEDURE [dbo].[PackagePathGetByPackageFullName]
	@PackageFullName	nvarchar(256) = NULL
AS
	SELECT	PackagePathID,
		PackageFullName,
		ParentPathID,
		PackagePathTypeID
	FROM	[dbo].[PackagePath]
	WHERE	(PackageFullName = @PackageFullName OR (PackageFullName IS NULL AND @PackageFullName IS NULL))
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[PackagePathGetAllByParentPathID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[PackagePathGetAllByParentPathID]
GO
CREATE PROCEDURE [dbo].[PackagePathGetAllByParentPathID]
	@ParentPathID		int = NULL
AS
	SELECT	PackagePathID,
		PackageFullName,
		ParentPathID,
		PackagePathTypeID
	FROM	[dbo].[PackagePath]
	WHERE	(ParentPathID = @ParentPathID OR (ParentPathID IS NULL AND @ParentPathID IS NULL))
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[PackagePathGetAll]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[PackagePathGetAll]
GO
CREATE PROCEDURE [dbo].[PackagePathGetAll]
AS
	SELECT	PackagePathID,
		PackageFullName,
		ParentPathID,
		PackagePathTypeID
	FROM	[dbo].[PackagePath]
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[PackagePathAdd]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[PackagePathAdd]
GO
CREATE PROCEDURE [dbo].[PackagePathAdd]
	@PackageFullName	nvarchar(256) = NULL,
	@ParentPathID		int = NULL,
	@PackagePathTypeID	int = 1
AS
	INSERT INTO  dbo.PackagePath (
		PackageFullName,
		ParentPathID,
		PackagePathTypeID
	)
	VALUES (
		@PackageFullName,
		@ParentPathID,
		@PackagePathTypeID
	)
	RETURN SCOPE_IDENTITY()
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[PackagePathBind]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[PackagePathBind]
GO
CREATE PROCEDURE [dbo].[PackagePathBind]
	@PackageFullName	nvarchar(256) = NULL,
	@ParentPathID		int = NULL,
	@PackagePathTypeID	int = 1
AS
	DECLARE	@ID	int

	SELECT	@ID = PackagePathID
	FROM	[dbo].[PackagePath]
	WHERE	(PackageFullName = @PackageFullName OR (PackageFullName IS NULL AND @PackageFullName IS NULL))

	IF @ID IS NULL
		EXEC @ID = PackagePathAdd @PackageFullName,
			@ParentPathID,
			@PackagePathTypeID

	RETURN @ID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[PackagePathSchema]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[PackagePathSchema]
GO
CREATE PROCEDURE [dbo].[PackagePathSchema]
AS
	SELECT
	'IF OBJECT_ID(''tempdb..#PackagePath'') IS NULL' + CAST(0x0A AS CHAR(1)) +
	'	CREATE TABLE #PackagePath (' + CAST(0x0A AS CHAR(1)) +
	'		PackagePathID		int NULL,' + CAST(0x0A AS CHAR(1)) +
	'		PackageFullName		nvarchar(256) COLLATE database_default NULL,' + CAST(0x0A AS CHAR(1)) +
	'		ParentPathID		int NULL,' + CAST(0x0A AS CHAR(1)) +
	'		PackagePathTypeID	int NOT NULL DEFAULT 1' + CAST(0x0A AS CHAR(1)) +
	'	)' + CAST(0x0A AS CHAR(1)) +
	'ELSE' + CAST(0x0A AS CHAR(1)) +
	'	DELETE FROM #PackagePath' + CAST(0x0A AS CHAR(1)) +
	'' AS SQL
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[PackagePathTempAdd]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[PackagePathTempAdd]
GO
CREATE PROCEDURE dbo.[PackagePathTempAdd]
	@PackagePathID		int,
	@PackageFullName	nvarchar(256) = NULL,
	@ParentPathID		int = NULL,
	@PackagePathTypeID	int = 1
AS
	INSERT INTO #PackagePath (
		PackagePathID,
		PackageFullName,
		ParentPathID,
		PackagePathTypeID
	)
	VALUES (
		@PackagePathID,
		@PackageFullName,
		@ParentPathID,
		@PackagePathTypeID
	)
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[PackagePathAddBatch]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[PackagePathAddBatch]
GO
CREATE PROCEDURE dbo.[PackagePathAddBatch]
AS
	DECLARE @count int
	INSERT dbo.PackagePath (
		PackageFullName,
		ParentPathID,
		PackagePathTypeID
	)
		SELECT	PackageFullName,
			ParentPathID,
			PackagePathTypeID
		FROM #PackagePath
	SET @count = @@ROWCOUNT
	DROP TABLE #PackagePath	-- Drop temporary table
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[PackagePathUpdateByID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[PackagePathUpdateByID]
GO
CREATE PROCEDURE [dbo].[PackagePathUpdateByID]
	@PackagePathID		int,
	@PackageFullName	nvarchar(256) = NULL,
	@ParentPathID		int = NULL,
	@PackagePathTypeID	int = 1
AS
	DECLARE	@ID	int
	SET @ID = 0

	UPDATE	[dbo].[PackagePath]
	SET	@ID = PackagePathID,
		PackageFullName = @PackageFullName,
		ParentPathID = @ParentPathID,
		PackagePathTypeID = @PackagePathTypeID
	WHERE	PackagePathID = @PackagePathID
	RETURN @ID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[PackagePathUpdateBatchByID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[PackagePathUpdateBatchByID]
GO
CREATE PROCEDURE dbo.[PackagePathUpdateBatchByID]
AS
	DECLARE @count int

	CREATE INDEX [TempPackagePathID]
		ON #PackagePath (PackagePathID)

	UPDATE	[dbo].[PackagePath]
	SET	PackageFullName = t.PackageFullName,
		ParentPathID = t.ParentPathID,
		PackagePathTypeID = t.PackagePathTypeID
	FROM	#PackagePath AS t
	WHERE	PackagePath.PackagePathID = t.PackagePathID
	SET @count = @@ROWCOUNT
	DROP TABLE #PackagePath	-- Drop the temporary table
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[PackagePathUpdateByPackageFullName]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[PackagePathUpdateByPackageFullName]
GO
CREATE PROCEDURE [dbo].[PackagePathUpdateByPackageFullName]
	@PackageFullName	nvarchar(256) = NULL,
	@ParentPathID		int = NULL,
	@PackagePathTypeID	int = 1
AS
	DECLARE	@ID	int
	SET @ID = 0

	UPDATE	[dbo].[PackagePath]
	SET	@ID = PackagePathID,
		ParentPathID = @ParentPathID,
		PackagePathTypeID = @PackagePathTypeID
	WHERE	(PackageFullName = @PackageFullName OR (PackageFullName IS NULL AND @PackageFullName IS NULL))
	RETURN @ID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[PackagePathUpdateBatchByPackageFullName]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[PackagePathUpdateBatchByPackageFullName]
GO
CREATE PROCEDURE dbo.[PackagePathUpdateBatchByPackageFullName]
AS
	DECLARE @count int

	CREATE INDEX [TempPackagePathPackageFullName]
		ON #PackagePath (PackageFullName)

	UPDATE	[dbo].[PackagePath]
	SET	ParentPathID = t.ParentPathID,
		PackagePathTypeID = t.PackagePathTypeID
	FROM	#PackagePath AS t
	WHERE	(PackagePath.PackageFullName = t.PackageFullName OR (PackagePath.PackageFullName IS NULL AND t.PackageFullName IS NULL))
	SET @count = @@ROWCOUNT
	DROP TABLE #PackagePath	-- Drop the temporary table
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[PackagePathPutByPackageFullName]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[PackagePathPutByPackageFullName]
GO
CREATE PROCEDURE [dbo].[PackagePathPutByPackageFullName]
	@PackageFullName	nvarchar(256) = NULL,
	@ParentPathID		int = NULL,
	@PackagePathTypeID	int = 1
AS
	DECLARE @ID	int

	SELECT	@ID = PackagePathID
	FROM	PackagePath
	WHERE	(PackageFullName = @PackageFullName OR (PackageFullName IS NULL AND @PackageFullName IS NULL))

	IF @ID IS NULL
		EXEC @ID = PackagePathAdd @PackageFullName,
			@ParentPathID,
			@PackagePathTypeID
	ELSE
		EXEC PackagePathUpdateByPackageFullName @PackageFullName,
			@ParentPathID,
			@PackagePathTypeID

	RETURN @ID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[PackagePathPutBatchByPackageFullName]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[PackagePathPutBatchByPackageFullName]
GO
CREATE PROCEDURE [dbo].[PackagePathPutBatchByPackageFullName]
AS
	DECLARE @count AS int
	SET @count = 0

	CREATE INDEX [TempPackagePathPackageFullName]
		ON #PackagePath (PackageFullName)

	BEGIN TRANSACTION
	UPDATE [dbo].[PackagePath]
		SET	ParentPathID = t.ParentPathID,
			PackagePathTypeID = t.PackagePathTypeID
		FROM	#PackagePath AS t
		WHERE	(PackagePath.PackageFullName = t.PackageFullName OR (PackagePath.PackageFullName IS NULL AND t.PackageFullName IS NULL))
	SET @count = @@ROWCOUNT

	INSERT [dbo].[PackagePath] (
		PackageFullName,
		ParentPathID,
		PackagePathTypeID
	)
		SELECT	PackageFullName,
			ParentPathID,
			PackagePathTypeID
		FROM	#PackagePath AS t
		WHERE NOT EXISTS(	-- Current record doesn't exist
			SELECT * FROM [dbo].[PackagePath]
			WHERE	(PackagePath.PackageFullName = t.PackageFullName OR (PackagePath.PackageFullName IS NULL AND t.PackageFullName IS NULL))
		)
	SET @count = @count + @@ROWCOUNT
	DROP TABLE #PackagePath	-- Drop the temporary table
	COMMIT WORK
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[PackagePathRemoveBatch]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[PackagePathRemoveBatch]
GO

CREATE PROCEDURE [dbo].[PackagePathRemoveBatch]
AS

	CREATE INDEX [TempPackagePathPackagePathRemoveBatch]
		ON #PackagePath (PackagePathID)	

	-- Delete records from PackagePath identified by fields of [TempPackagePathPackagePathRemoveBatch]
	DELETE [dbo].[PackagePath]
	WHERE EXISTS(
			SELECT * FROM #PackagePath AS t
			WHERE	PackagePath.PackagePathID = t.PackagePathID
		)
	DROP TABLE #PackagePath      -- Drop the temporary table
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[PackagePathRemoveByID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[PackagePathRemoveByID]
GO
CREATE PROCEDURE [dbo].[PackagePathRemoveByID]
	@PackagePathID		int
AS
	-- PackagePath deletes cascade to:
	--	PackageVersion by FK_PackageVersion_PackagePath
	--		PackageVersionInState by FK_PackageVersionInState_PackageVersion
	--		PackageProvides by FK_PackageProvides_PackageVersion
	--		PackageRequires by FK_PackageRequires_PackageVersion
	--		MediaContainsPackageVersion by FK_MCPV_PackageVersion
	--		PackageVersionLocale by FK_PackageVersionLocale_PackageVersion
	--		PackageVersionArchitecture by FK_PackageVersionArchitecture_PackageVersion
	--		PackageVersionEnvironment by FK_PackageVersionEnvironment_PackageVersion
	--		Installation by FK_Installation_PackageVersion
	--		InstallationHistory by FK_InstallationHistory_PackageVersion
	--	MediaContainsPackagePath by FK_MCPP_PackagePath
	--	SoftwareOccurrence by FK_SoftwareOccurrence_Package
	--		SoftwareValue by FK_SoftwareValue_SoftwareOccurrence
	--	PackageAllocation by FK_Allocation_PackagePath
	--	PackageApplies by FK_PackageApplies_PackagePath
	--	InstallationPostponement by FK_InstallationPostponement_PackagePath
	--	Task by FK_Task_PackagePath
	--		Job by FK_Job_Task
	--			Action by FK_Action_Job
	--				ActionApplies by FK_ActionApplies_Action
	-- PackagePath deletes may fail due to non-cascading FKs:
	--	PackagePath by FK_PackagePath_ParentPath
	--	(through PackageVersion by FK_PackageVersion_PackagePath)
	--		DistributedPackage by FK_DistributedPackage_Confirmed
	--		DistributedPackage by FK_DistributedPackage_Requested
	--	(through Task by FK_Task_PackagePath)
	--		Action by FK_Action_Task
	DELETE	[dbo].[PackagePath]
	WHERE	PackagePathID = @PackagePathID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[PackagePathRemoveAll]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[PackagePathRemoveAll]
GO
CREATE PROCEDURE [dbo].[PackagePathRemoveAll]
	
AS
	DELETE	[dbo].[PackagePath]
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ArchitectureGetByID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ArchitectureGetByID]
GO
CREATE PROCEDURE [dbo].[ArchitectureGetByID]
	@ArchitectureID		int
AS
	SELECT	ArchitectureID,
		ArchitectureName
	FROM	[dbo].[Architecture]
	WHERE	ArchitectureID = @ArchitectureID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ArchitectureGetByName]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ArchitectureGetByName]
GO
CREATE PROCEDURE [dbo].[ArchitectureGetByName]
	@ArchitectureName	nvarchar(64)
AS
	SELECT	ArchitectureID,
		ArchitectureName
	FROM	[dbo].[Architecture]
	WHERE	ArchitectureName = @ArchitectureName
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ArchitectureGetAll]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ArchitectureGetAll]
GO
CREATE PROCEDURE [dbo].[ArchitectureGetAll]
AS
	SELECT	ArchitectureID,
		ArchitectureName
	FROM	[dbo].[Architecture]
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ArchitectureAdd]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ArchitectureAdd]
GO
CREATE PROCEDURE [dbo].[ArchitectureAdd]
	@ArchitectureName	nvarchar(64)
AS
	INSERT INTO  dbo.Architecture (
		ArchitectureName
	)
	VALUES (
		@ArchitectureName
	)
	RETURN SCOPE_IDENTITY()
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ArchitectureBind]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ArchitectureBind]
GO
CREATE PROCEDURE [dbo].[ArchitectureBind]
	@ArchitectureName	nvarchar(64)
AS
	DECLARE	@ID	int

	SELECT	@ID = ArchitectureID
	FROM	[dbo].[Architecture]
	WHERE	ArchitectureName = @ArchitectureName

	IF @ID IS NULL
		EXEC @ID = ArchitectureAdd @ArchitectureName

	RETURN @ID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ArchitectureSchema]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ArchitectureSchema]
GO
CREATE PROCEDURE [dbo].[ArchitectureSchema]
AS
	SELECT
	'IF OBJECT_ID(''tempdb..#Architecture'') IS NULL' + CAST(0x0A AS CHAR(1)) +
	'	CREATE TABLE #Architecture (' + CAST(0x0A AS CHAR(1)) +
	'		ArchitectureID		int NULL,' + CAST(0x0A AS CHAR(1)) +
	'		ArchitectureName	nvarchar(64) COLLATE database_default NOT NULL' + CAST(0x0A AS CHAR(1)) +
	'	)' + CAST(0x0A AS CHAR(1)) +
	'ELSE' + CAST(0x0A AS CHAR(1)) +
	'	DELETE FROM #Architecture' + CAST(0x0A AS CHAR(1)) +
	'' AS SQL
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ArchitectureTempAdd]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ArchitectureTempAdd]
GO
CREATE PROCEDURE dbo.[ArchitectureTempAdd]
	@ArchitectureID		int,
	@ArchitectureName	nvarchar(64)
AS
	INSERT INTO #Architecture (
		ArchitectureID,
		ArchitectureName
	)
	VALUES (
		@ArchitectureID,
		@ArchitectureName
	)
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ArchitectureAddBatch]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ArchitectureAddBatch]
GO
CREATE PROCEDURE dbo.[ArchitectureAddBatch]
AS
	DECLARE @count int
	INSERT dbo.Architecture (
		ArchitectureName
	)
		SELECT	ArchitectureName
		FROM #Architecture
	SET @count = @@ROWCOUNT
	DROP TABLE #Architecture	-- Drop temporary table
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ArchitectureUpdateByID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ArchitectureUpdateByID]
GO
CREATE PROCEDURE [dbo].[ArchitectureUpdateByID]
	@ArchitectureID		int,
	@ArchitectureName	nvarchar(64)
AS
	DECLARE	@ID	int
	SET @ID = 0

	UPDATE	[dbo].[Architecture]
	SET	@ID = ArchitectureID,
		ArchitectureName = @ArchitectureName
	WHERE	ArchitectureID = @ArchitectureID
	RETURN @ID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ArchitectureUpdateBatchByID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ArchitectureUpdateBatchByID]
GO
CREATE PROCEDURE dbo.[ArchitectureUpdateBatchByID]
AS
	DECLARE @count int

	CREATE INDEX [TempArchitectureID]
		ON #Architecture (ArchitectureID)

	UPDATE	[dbo].[Architecture]
	SET	ArchitectureName = t.ArchitectureName
	FROM	#Architecture AS t
	WHERE	Architecture.ArchitectureID = t.ArchitectureID
	SET @count = @@ROWCOUNT
	DROP TABLE #Architecture	-- Drop the temporary table
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ArchitecturePutByName]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ArchitecturePutByName]
GO
CREATE PROCEDURE [dbo].[ArchitecturePutByName]
	@ArchitectureName	nvarchar(64)
AS
	DECLARE @ID	int

	SELECT	@ID = ArchitectureID
	FROM	Architecture
	WHERE	ArchitectureName = @ArchitectureName

	IF @ID IS NULL
		EXEC @ID = ArchitectureAdd @ArchitectureName

	RETURN @ID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ArchitecturePutBatchByName]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ArchitecturePutBatchByName]
GO
CREATE PROCEDURE [dbo].[ArchitecturePutBatchByName]
AS
	DECLARE @count AS int
	SET @count = 0

	CREATE INDEX [TempArchitectureName]
		ON #Architecture (ArchitectureName)

	BEGIN TRANSACTION

	INSERT [dbo].[Architecture] (
		ArchitectureName
	)
		SELECT	ArchitectureName
		FROM	#Architecture AS t
		WHERE NOT EXISTS(	-- Current record doesn't exist
			SELECT * FROM [dbo].[Architecture]
			WHERE	Architecture.ArchitectureName = t.ArchitectureName
		)
	SET @count = @count + @@ROWCOUNT
	DROP TABLE #Architecture	-- Drop the temporary table
	COMMIT WORK
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ArchitectureRemoveBatch]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ArchitectureRemoveBatch]
GO

CREATE PROCEDURE [dbo].[ArchitectureRemoveBatch]
AS

	CREATE INDEX [TempArchitectureArchitectureRemoveBatch]
		ON #Architecture (ArchitectureID)	

	-- Delete records from Architecture identified by fields of [TempArchitectureArchitectureRemoveBatch]
	DELETE [dbo].[Architecture]
	WHERE EXISTS(
			SELECT * FROM #Architecture AS t
			WHERE	Architecture.ArchitectureID = t.ArchitectureID
		)
	DROP TABLE #Architecture      -- Drop the temporary table
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ArchitectureRemoveByName]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ArchitectureRemoveByName]
GO
CREATE PROCEDURE [dbo].[ArchitectureRemoveByName]
	@ArchitectureName	nvarchar(64)
AS
	-- Architecture deletes cascade to:
	--	PackageVersionArchitecture by FK_PackageVersionArchitecture_Architecture
	DELETE	[dbo].[Architecture]
	WHERE	ArchitectureName = @ArchitectureName
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ArchitectureRemoveAll]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ArchitectureRemoveAll]
GO
CREATE PROCEDURE [dbo].[ArchitectureRemoveAll]
	
AS
	DELETE	[dbo].[Architecture]
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[PackageVersionGetByID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[PackageVersionGetByID]
GO
CREATE PROCEDURE [dbo].[PackageVersionGetByID]
	@PackageVersionID	int
AS
	SELECT	PackageVersionID,
		PackagePathID,
		Version,
		[Update],
		PackageFamilyID,
		Title,
		MD5,
		[Size],
		Category
	FROM	[dbo].[PackageVersion]
	WHERE	PackageVersionID = @PackageVersionID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[PackageVersionGetByPackagePathIDVersionUpdate]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[PackageVersionGetByPackagePathIDVersionUpdate]
GO
CREATE PROCEDURE [dbo].[PackageVersionGetByPackagePathIDVersionUpdate]
	@PackagePathID		int,
	@Version		nvarchar(32),
	@Update			nvarchar(64) = ''
AS
	SELECT	PackageVersionID,
		PackagePathID,
		Version,
		[Update],
		PackageFamilyID,
		Title,
		MD5,
		[Size],
		Category
	FROM	[dbo].[PackageVersion]
	WHERE	PackagePathID = @PackagePathID
	  AND	Version = @Version
	  AND	[Update] = @Update
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[PackageVersionGetAllByPackagePathID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[PackageVersionGetAllByPackagePathID]
GO
CREATE PROCEDURE [dbo].[PackageVersionGetAllByPackagePathID]
	@PackagePathID		int
AS
	SELECT	PackageVersionID,
		PackagePathID,
		Version,
		[Update],
		PackageFamilyID,
		Title,
		MD5,
		[Size],
		Category
	FROM	[dbo].[PackageVersion]
	WHERE	PackagePathID = @PackagePathID
	ORDER BY Version, [Update]
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[PackageVersionGetAll]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[PackageVersionGetAll]
GO
CREATE PROCEDURE [dbo].[PackageVersionGetAll]
AS
	SELECT	PackageVersionID,
		PackagePathID,
		Version,
		[Update],
		PackageFamilyID,
		Title,
		MD5,
		[Size],
		Category
	FROM	[dbo].[PackageVersion]
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[PackageVersionAdd]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[PackageVersionAdd]
GO
CREATE PROCEDURE [dbo].[PackageVersionAdd]
	@PackagePathID		int,
	@Version		nvarchar(32),
	@Update			nvarchar(64) = '',
	@PackageFamilyID	int,
	@Title			nvarchar(64) = NULL,
	@MD5			nvarchar(40) = NULL,
	@Size			int = NULL,
	@Category		nvarchar(128) = NULL
AS
	INSERT INTO  dbo.PackageVersion (
		PackagePathID,
		Version,
		[Update],
		PackageFamilyID,
		Title,
		MD5,
		[Size],
		Category
	)
	VALUES (
		@PackagePathID,
		@Version,
		@Update,
		@PackageFamilyID,
		@Title,
		@MD5,
		@Size,
		@Category
	)
	RETURN SCOPE_IDENTITY()
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[PackageVersionBind]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[PackageVersionBind]
GO
CREATE PROCEDURE [dbo].[PackageVersionBind]
	@PackagePathID		int,
	@Version		nvarchar(32),
	@Update			nvarchar(64) = '',
	@PackageFamilyID	int,
	@Title			nvarchar(64) = NULL,
	@MD5			nvarchar(40) = NULL,
	@Size			int = NULL,
	@Category		nvarchar(128) = NULL
AS
	DECLARE	@ID	int

	SELECT	@ID = PackageVersionID
	FROM	[dbo].[PackageVersion]
	WHERE	PackagePathID = @PackagePathID
	  AND	Version = @Version
	  AND	[Update] = @Update

	IF @ID IS NULL
		EXEC @ID = PackageVersionAdd @PackagePathID,
			@Version,
			@Update,
			@PackageFamilyID,
			@Title,
			@MD5,
			@Size,
			@Category

	RETURN @ID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[PackageVersionSchema]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[PackageVersionSchema]
GO
CREATE PROCEDURE [dbo].[PackageVersionSchema]
AS
	SELECT
	'IF OBJECT_ID(''tempdb..#PackageVersion'') IS NULL' + CAST(0x0A AS CHAR(1)) +
	'	CREATE TABLE #PackageVersion (' + CAST(0x0A AS CHAR(1)) +
	'		PackageVersionID	int NULL,' + CAST(0x0A AS CHAR(1)) +
	'		PackagePathID		int NOT NULL,' + CAST(0x0A AS CHAR(1)) +
	'		Version			nvarchar(32) COLLATE database_default NOT NULL,' + CAST(0x0A AS CHAR(1)) +
	'		[Update]		nvarchar(64) COLLATE database_default NOT NULL DEFAULT '''',' + CAST(0x0A AS CHAR(1)) +
	'		PackageFamilyID		int NOT NULL,' + CAST(0x0A AS CHAR(1)) +
	'		Title			nvarchar(64) COLLATE database_default NULL,' + CAST(0x0A AS CHAR(1)) +
	'		MD5			nvarchar(40) COLLATE database_default NULL,' + CAST(0x0A AS CHAR(1)) +
	'		[Size]			int NULL,' + CAST(0x0A AS CHAR(1)) +
	'		Category		nvarchar(128) COLLATE database_default NULL' + CAST(0x0A AS CHAR(1)) +
	'	)' + CAST(0x0A AS CHAR(1)) +
	'ELSE' + CAST(0x0A AS CHAR(1)) +
	'	DELETE FROM #PackageVersion' + CAST(0x0A AS CHAR(1)) +
	'' AS SQL
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[PackageVersionTempAdd]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[PackageVersionTempAdd]
GO
CREATE PROCEDURE dbo.[PackageVersionTempAdd]
	@PackageVersionID	int,
	@PackagePathID		int,
	@Version		nvarchar(32),
	@Update			nvarchar(64) = '',
	@PackageFamilyID	int,
	@Title			nvarchar(64) = NULL,
	@MD5			nvarchar(40) = NULL,
	@Size			int = NULL,
	@Category		nvarchar(128) = NULL
AS
	INSERT INTO #PackageVersion (
		PackageVersionID,
		PackagePathID,
		Version,
		[Update],
		PackageFamilyID,
		Title,
		MD5,
		[Size],
		Category
	)
	VALUES (
		@PackageVersionID,
		@PackagePathID,
		@Version,
		@Update,
		@PackageFamilyID,
		@Title,
		@MD5,
		@Size,
		@Category
	)
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[PackageVersionAddBatch]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[PackageVersionAddBatch]
GO
CREATE PROCEDURE dbo.[PackageVersionAddBatch]
AS
	DECLARE @count int
	INSERT dbo.PackageVersion (
		PackagePathID,
		Version,
		[Update],
		PackageFamilyID,
		Title,
		MD5,
		[Size],
		Category
	)
		SELECT	PackagePathID,
			Version,
			[Update],
			PackageFamilyID,
			Title,
			MD5,
			[Size],
			Category
		FROM #PackageVersion
	SET @count = @@ROWCOUNT
	DROP TABLE #PackageVersion	-- Drop temporary table
	RETURN @count
GO

/*
Add new PackageVersion bound to
	PackageFamily using PackageName
	with PackagePathID, Version, Update, Title, MD5, Size, Category
*/

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[PackageVersionUpdateByID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[PackageVersionUpdateByID]
GO
CREATE PROCEDURE [dbo].[PackageVersionUpdateByID]
	@PackageVersionID	int,
	@PackagePathID		int,
	@Version		nvarchar(32),
	@Update			nvarchar(64) = '',
	@PackageFamilyID	int,
	@Title			nvarchar(64) = NULL,
	@MD5			nvarchar(40) = NULL,
	@Size			int = NULL,
	@Category		nvarchar(128) = NULL
AS
	DECLARE	@ID	int
	SET @ID = 0

	UPDATE	[dbo].[PackageVersion]
	SET	@ID = PackageVersionID,
		PackagePathID = @PackagePathID,
		Version = @Version,
		[Update] = @Update,
		PackageFamilyID = @PackageFamilyID,
		Title = @Title,
		MD5 = @MD5,
		[Size] = @Size,
		Category = @Category
	WHERE	PackageVersionID = @PackageVersionID
	RETURN @ID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[PackageVersionUpdateBatchByID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[PackageVersionUpdateBatchByID]
GO
CREATE PROCEDURE dbo.[PackageVersionUpdateBatchByID]
AS
	DECLARE @count int

	CREATE INDEX [TempPackageVersionID]
		ON #PackageVersion (PackageVersionID)

	UPDATE	[dbo].[PackageVersion]
	SET	PackagePathID = t.PackagePathID,
		Version = t.Version,
		[Update] = t.[Update],
		PackageFamilyID = t.PackageFamilyID,
		Title = t.Title,
		MD5 = t.MD5,
		[Size] = t.[Size],
		Category = t.Category
	FROM	#PackageVersion AS t
	WHERE	PackageVersion.PackageVersionID = t.PackageVersionID
	SET @count = @@ROWCOUNT
	DROP TABLE #PackageVersion	-- Drop the temporary table
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[PackageVersionUpdateByPackagePathIDVersionUpdate]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[PackageVersionUpdateByPackagePathIDVersionUpdate]
GO
CREATE PROCEDURE [dbo].[PackageVersionUpdateByPackagePathIDVersionUpdate]
	@PackagePathID		int,
	@Version		nvarchar(32),
	@Update			nvarchar(64) = '',
	@PackageFamilyID	int,
	@Title			nvarchar(64) = NULL,
	@MD5			nvarchar(40) = NULL,
	@Size			int = NULL,
	@Category		nvarchar(128) = NULL
AS
	DECLARE	@ID	int
	SET @ID = 0

	UPDATE	[dbo].[PackageVersion]
	SET	@ID = PackageVersionID,
		PackageFamilyID = @PackageFamilyID,
		Title = @Title,
		MD5 = @MD5,
		[Size] = @Size,
		Category = @Category
	WHERE	PackagePathID = @PackagePathID
	  AND	Version = @Version
	  AND	[Update] = @Update
	RETURN @ID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[PackageVersionUpdateBatchByPackagePathIDVersionUpdate]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[PackageVersionUpdateBatchByPackagePathIDVersionUpdate]
GO
CREATE PROCEDURE dbo.[PackageVersionUpdateBatchByPackagePathIDVersionUpdate]
AS
	DECLARE @count int

	CREATE INDEX [TempPackageVersionPackagePathIDVersionUpdate]
		ON #PackageVersion (PackagePathID, Version, [Update])

	UPDATE	[dbo].[PackageVersion]
	SET	PackageFamilyID = t.PackageFamilyID,
		Title = t.Title,
		MD5 = t.MD5,
		[Size] = t.[Size],
		Category = t.Category
	FROM	#PackageVersion AS t
	WHERE	PackageVersion.PackagePathID = t.PackagePathID
	  AND	PackageVersion.Version = t.Version
	  AND	PackageVersion.[Update] = t.[Update]
	SET @count = @@ROWCOUNT
	DROP TABLE #PackageVersion	-- Drop the temporary table
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[PackageVersionPutByPackagePathIDVersionUpdate]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[PackageVersionPutByPackagePathIDVersionUpdate]
GO
CREATE PROCEDURE [dbo].[PackageVersionPutByPackagePathIDVersionUpdate]
	@PackagePathID		int,
	@Version		nvarchar(32),
	@Update			nvarchar(64) = '',
	@PackageFamilyID	int,
	@Title			nvarchar(64) = NULL,
	@MD5			nvarchar(40) = NULL,
	@Size			int = NULL,
	@Category		nvarchar(128) = NULL
AS
	DECLARE @ID	int

	SELECT	@ID = PackageVersionID
	FROM	PackageVersion
	WHERE	PackagePathID = @PackagePathID
	  AND	Version = @Version
	  AND	[Update] = @Update

	IF @ID IS NULL
		EXEC @ID = PackageVersionAdd @PackagePathID,
			@Version,
			@Update,
			@PackageFamilyID,
			@Title,
			@MD5,
			@Size,
			@Category
	ELSE
		EXEC PackageVersionUpdateByPackagePathIDVersionUpdate @PackagePathID,
			@Version,
			@Update,
			@PackageFamilyID,
			@Title,
			@MD5,
			@Size,
			@Category

	RETURN @ID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[PackageVersionPutBatchByPackagePathIDVersionUpdate]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[PackageVersionPutBatchByPackagePathIDVersionUpdate]
GO
CREATE PROCEDURE [dbo].[PackageVersionPutBatchByPackagePathIDVersionUpdate]
AS
	DECLARE @count AS int
	SET @count = 0

	CREATE INDEX [TempPackageVersionPackagePathIDVersionUpdate]
		ON #PackageVersion (PackagePathID, Version, [Update])

	BEGIN TRANSACTION
	UPDATE [dbo].[PackageVersion]
		SET	PackageFamilyID = t.PackageFamilyID,
			Title = t.Title,
			MD5 = t.MD5,
			[Size] = t.[Size],
			Category = t.Category
		FROM	#PackageVersion AS t
		WHERE	PackageVersion.PackagePathID = t.PackagePathID
		  AND	PackageVersion.Version = t.Version
		  AND	PackageVersion.[Update] = t.[Update]
	SET @count = @@ROWCOUNT

	INSERT [dbo].[PackageVersion] (
		PackagePathID,
		Version,
		[Update],
		PackageFamilyID,
		Title,
		MD5,
		[Size],
		Category
	)
		SELECT	PackagePathID,
			Version,
			[Update],
			PackageFamilyID,
			Title,
			MD5,
			[Size],
			Category
		FROM	#PackageVersion AS t
		WHERE NOT EXISTS(	-- Current record doesn't exist
			SELECT * FROM [dbo].[PackageVersion]
			WHERE	PackageVersion.PackagePathID = t.PackagePathID
			  AND	PackageVersion.Version = t.Version
			  AND	PackageVersion.[Update] = t.[Update]
		)
	SET @count = @count + @@ROWCOUNT
	DROP TABLE #PackageVersion	-- Drop the temporary table
	COMMIT WORK
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[PackageVersionRemoveBatch]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[PackageVersionRemoveBatch]
GO

CREATE PROCEDURE [dbo].[PackageVersionRemoveBatch]
AS

	CREATE INDEX [TempPackageVersionPackageVersionRemoveBatch]
		ON #PackageVersion (PackageVersionID)	

	-- Delete records from PackageVersion identified by fields of [TempPackageVersionPackageVersionRemoveBatch]
	DELETE [dbo].[PackageVersion]
	WHERE EXISTS(
			SELECT * FROM #PackageVersion AS t
			WHERE	PackageVersion.PackageVersionID = t.PackageVersionID
		)
	DROP TABLE #PackageVersion      -- Drop the temporary table
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[PackageVersionRemoveByID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[PackageVersionRemoveByID]
GO
CREATE PROCEDURE [dbo].[PackageVersionRemoveByID]
	@PackageVersionID	int
AS
	-- PackageVersion deletes cascade to:
	--	PackageVersionInState by FK_PackageVersionInState_PackageVersion
	--	PackageProvides by FK_PackageProvides_PackageVersion
	--	PackageRequires by FK_PackageRequires_PackageVersion
	--	MediaContainsPackageVersion by FK_MCPV_PackageVersion
	--	PackageVersionLocale by FK_PackageVersionLocale_PackageVersion
	--	PackageVersionArchitecture by FK_PackageVersionArchitecture_PackageVersion
	--	PackageVersionEnvironment by FK_PackageVersionEnvironment_PackageVersion
	--	Installation by FK_Installation_PackageVersion
	--	InstallationHistory by FK_InstallationHistory_PackageVersion
	-- PackageVersion deletes may fail due to non-cascading FKs:
	--	DistributedPackage by FK_DistributedPackage_Confirmed
	--	DistributedPackage by FK_DistributedPackage_Requested
	DELETE	[dbo].[PackageVersion]
	WHERE	PackageVersionID = @PackageVersionID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[PackageVersionRemoveByPackagePathIDVersionUpdate]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[PackageVersionRemoveByPackagePathIDVersionUpdate]
GO
CREATE PROCEDURE [dbo].[PackageVersionRemoveByPackagePathIDVersionUpdate]
	@PackagePathID		int,
	@Version		nvarchar(32),
	@Update			nvarchar(64) = ''
AS
	-- PackageVersion deletes cascade to:
	--	PackageVersionInState by FK_PackageVersionInState_PackageVersion
	--	PackageProvides by FK_PackageProvides_PackageVersion
	--	PackageRequires by FK_PackageRequires_PackageVersion
	--	MediaContainsPackageVersion by FK_MCPV_PackageVersion
	--	PackageVersionLocale by FK_PackageVersionLocale_PackageVersion
	--	PackageVersionArchitecture by FK_PackageVersionArchitecture_PackageVersion
	--	PackageVersionEnvironment by FK_PackageVersionEnvironment_PackageVersion
	--	Installation by FK_Installation_PackageVersion
	--	InstallationHistory by FK_InstallationHistory_PackageVersion
	-- PackageVersion deletes may fail due to non-cascading FKs:
	--	DistributedPackage by FK_DistributedPackage_Confirmed
	--	DistributedPackage by FK_DistributedPackage_Requested
	DELETE	[dbo].[PackageVersion]
	WHERE	PackagePathID = @PackagePathID
	  AND	Version = @Version
	  AND	[Update] = @Update
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[PackageVersionRemoveAll]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[PackageVersionRemoveAll]
GO
CREATE PROCEDURE [dbo].[PackageVersionRemoveAll]
	
AS
	DELETE	[dbo].[PackageVersion]
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[PackageProvidesGetByID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[PackageProvidesGetByID]
GO
CREATE PROCEDURE [dbo].[PackageProvidesGetByID]
	@PackageProvidesID	int
AS
	SELECT	PackageProvidesID,
		PackageVersionID,
		PackageFamilyID,
		Version
	FROM	[dbo].[PackageProvides]
	WHERE	PackageProvidesID = @PackageProvidesID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[PackageProvidesGetByPackageVersionIDPackageFamilyIDVersion]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[PackageProvidesGetByPackageVersionIDPackageFamilyIDVersion]
GO
CREATE PROCEDURE [dbo].[PackageProvidesGetByPackageVersionIDPackageFamilyIDVersion]
	@PackageVersionID	int,
	@PackageFamilyID	int,
	@Version		nvarchar(32) = NULL
AS
	SELECT	PackageProvidesID,
		PackageVersionID,
		PackageFamilyID,
		Version
	FROM	[dbo].[PackageProvides]
	WHERE	PackageVersionID = @PackageVersionID
	  AND	PackageFamilyID = @PackageFamilyID
	  AND	(Version = @Version OR (Version IS NULL AND @Version IS NULL))
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[PackageProvidesGetAll]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[PackageProvidesGetAll]
GO
CREATE PROCEDURE [dbo].[PackageProvidesGetAll]
AS
	SELECT	PackageProvidesID,
		PackageVersionID,
		PackageFamilyID,
		Version
	FROM	[dbo].[PackageProvides]
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[PackageProvidesAdd]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[PackageProvidesAdd]
GO
CREATE PROCEDURE [dbo].[PackageProvidesAdd]
	@PackageVersionID	int,
	@PackageFamilyID	int,
	@Version		nvarchar(32) = NULL
AS
	INSERT INTO  dbo.PackageProvides (
		PackageVersionID,
		PackageFamilyID,
		Version
	)
	VALUES (
		@PackageVersionID,
		@PackageFamilyID,
		@Version
	)
	RETURN SCOPE_IDENTITY()
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[PackageProvidesBind]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[PackageProvidesBind]
GO
CREATE PROCEDURE [dbo].[PackageProvidesBind]
	@PackageVersionID	int,
	@PackageFamilyID	int,
	@Version		nvarchar(32) = NULL
AS
	DECLARE	@ID	int

	SELECT	@ID = PackageProvidesID
	FROM	[dbo].[PackageProvides]
	WHERE	PackageVersionID = @PackageVersionID
	  AND	PackageFamilyID = @PackageFamilyID
	  AND	(Version = @Version OR (Version IS NULL AND @Version IS NULL))

	IF @ID IS NULL
		EXEC @ID = PackageProvidesAdd @PackageVersionID,
			@PackageFamilyID,
			@Version

	RETURN @ID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[PackageProvidesSchema]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[PackageProvidesSchema]
GO
CREATE PROCEDURE [dbo].[PackageProvidesSchema]
AS
	SELECT
	'IF OBJECT_ID(''tempdb..#PackageProvides'') IS NULL' + CAST(0x0A AS CHAR(1)) +
	'	CREATE TABLE #PackageProvides (' + CAST(0x0A AS CHAR(1)) +
	'		PackageProvidesID	int NULL,' + CAST(0x0A AS CHAR(1)) +
	'		PackageVersionID	int NOT NULL,' + CAST(0x0A AS CHAR(1)) +
	'		PackageFamilyID		int NOT NULL,' + CAST(0x0A AS CHAR(1)) +
	'		Version			nvarchar(32) COLLATE database_default NULL' + CAST(0x0A AS CHAR(1)) +
	'	)' + CAST(0x0A AS CHAR(1)) +
	'ELSE' + CAST(0x0A AS CHAR(1)) +
	'	DELETE FROM #PackageProvides' + CAST(0x0A AS CHAR(1)) +
	'' AS SQL
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[PackageProvidesTempAdd]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[PackageProvidesTempAdd]
GO
CREATE PROCEDURE dbo.[PackageProvidesTempAdd]
	@PackageProvidesID	int,
	@PackageVersionID	int,
	@PackageFamilyID	int,
	@Version		nvarchar(32) = NULL
AS
	INSERT INTO #PackageProvides (
		PackageProvidesID,
		PackageVersionID,
		PackageFamilyID,
		Version
	)
	VALUES (
		@PackageProvidesID,
		@PackageVersionID,
		@PackageFamilyID,
		@Version
	)
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[PackageProvidesAddBatch]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[PackageProvidesAddBatch]
GO
CREATE PROCEDURE dbo.[PackageProvidesAddBatch]
AS
	DECLARE @count int
	INSERT dbo.PackageProvides (
		PackageVersionID,
		PackageFamilyID,
		Version
	)
		SELECT	PackageVersionID,
			PackageFamilyID,
			Version
		FROM #PackageProvides
	SET @count = @@ROWCOUNT
	DROP TABLE #PackageProvides	-- Drop temporary table
	RETURN @count
GO

/*
Add new PackageProvides bound to
	PackageFamily using PackageName
	PackageVersion using PackagePathID, Version, Update with PackageFamilyID
	with Version
*/

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[PackageProvidesUpdateByID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[PackageProvidesUpdateByID]
GO
CREATE PROCEDURE [dbo].[PackageProvidesUpdateByID]
	@PackageProvidesID	int,
	@PackageVersionID	int,
	@PackageFamilyID	int,
	@Version		nvarchar(32) = NULL
AS
	DECLARE	@ID	int
	SET @ID = 0

	UPDATE	[dbo].[PackageProvides]
	SET	@ID = PackageProvidesID,
		PackageVersionID = @PackageVersionID,
		PackageFamilyID = @PackageFamilyID,
		Version = @Version
	WHERE	PackageProvidesID = @PackageProvidesID
	RETURN @ID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[PackageProvidesUpdateBatchByID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[PackageProvidesUpdateBatchByID]
GO
CREATE PROCEDURE dbo.[PackageProvidesUpdateBatchByID]
AS
	DECLARE @count int

	CREATE INDEX [TempPackageProvidesID]
		ON #PackageProvides (PackageProvidesID)

	UPDATE	[dbo].[PackageProvides]
	SET	PackageVersionID = t.PackageVersionID,
		PackageFamilyID = t.PackageFamilyID,
		Version = t.Version
	FROM	#PackageProvides AS t
	WHERE	PackageProvides.PackageProvidesID = t.PackageProvidesID
	SET @count = @@ROWCOUNT
	DROP TABLE #PackageProvides	-- Drop the temporary table
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[PackageProvidesPutByPackageVersionIDPackageFamilyIDVersion]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[PackageProvidesPutByPackageVersionIDPackageFamilyIDVersion]
GO
CREATE PROCEDURE [dbo].[PackageProvidesPutByPackageVersionIDPackageFamilyIDVersion]
	@PackageVersionID	int,
	@PackageFamilyID	int,
	@Version		nvarchar(32) = NULL
AS
	DECLARE @ID	int

	SELECT	@ID = PackageProvidesID
	FROM	PackageProvides
	WHERE	PackageVersionID = @PackageVersionID
	  AND	PackageFamilyID = @PackageFamilyID
	  AND	(Version = @Version OR (Version IS NULL AND @Version IS NULL))

	IF @ID IS NULL
		EXEC @ID = PackageProvidesAdd @PackageVersionID,
			@PackageFamilyID,
			@Version

	RETURN @ID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[PackageProvidesPutBatchByPackageVersionIDPackageFamilyIDVersion]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[PackageProvidesPutBatchByPackageVersionIDPackageFamilyIDVersion]
GO
CREATE PROCEDURE [dbo].[PackageProvidesPutBatchByPackageVersionIDPackageFamilyIDVersion]
AS
	DECLARE @count AS int
	SET @count = 0

	CREATE INDEX [TempPackageProvidesPackageVersionIDPackageFamilyIDVersion]
		ON #PackageProvides (PackageVersionID, PackageFamilyID, Version)

	BEGIN TRANSACTION

	INSERT [dbo].[PackageProvides] (
		PackageVersionID,
		PackageFamilyID,
		Version
	)
		SELECT	PackageVersionID,
			PackageFamilyID,
			Version
		FROM	#PackageProvides AS t
		WHERE NOT EXISTS(	-- Current record doesn't exist
			SELECT * FROM [dbo].[PackageProvides]
			WHERE	PackageProvides.PackageVersionID = t.PackageVersionID
			  AND	PackageProvides.PackageFamilyID = t.PackageFamilyID
			  AND	(PackageProvides.Version = t.Version OR (PackageProvides.Version IS NULL AND t.Version IS NULL))
		)
	SET @count = @count + @@ROWCOUNT
	DROP TABLE #PackageProvides	-- Drop the temporary table
	COMMIT WORK
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[PackageProvidesRemoveBatch]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[PackageProvidesRemoveBatch]
GO

CREATE PROCEDURE [dbo].[PackageProvidesRemoveBatch]
AS

	CREATE INDEX [TempPackageProvidesPackageProvidesRemoveBatch]
		ON #PackageProvides (PackageProvidesID)	

	-- Delete records from PackageProvides identified by fields of [TempPackageProvidesPackageProvidesRemoveBatch]
	DELETE [dbo].[PackageProvides]
	WHERE EXISTS(
			SELECT * FROM #PackageProvides AS t
			WHERE	PackageProvides.PackageProvidesID = t.PackageProvidesID
		)
	DROP TABLE #PackageProvides      -- Drop the temporary table
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[PackageProvidesRemoveByID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[PackageProvidesRemoveByID]
GO
CREATE PROCEDURE [dbo].[PackageProvidesRemoveByID]
	@PackageProvidesID	int
AS
	DELETE	[dbo].[PackageProvides]
	WHERE	PackageProvidesID = @PackageProvidesID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[PackageProvidesRemoveAllByPackageVersionID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[PackageProvidesRemoveAllByPackageVersionID]
GO
CREATE PROCEDURE [dbo].[PackageProvidesRemoveAllByPackageVersionID]
	@PackageVersionID	int
AS
	DELETE	[dbo].[PackageProvides]
	WHERE	PackageVersionID = @PackageVersionID
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[PackageProvidesRemoveAll]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[PackageProvidesRemoveAll]
GO
CREATE PROCEDURE [dbo].[PackageProvidesRemoveAll]
	
AS
	DELETE	[dbo].[PackageProvides]
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[PackageRequiresGetByPackageVersionIDRequiredTypeRequiredObjectMatch]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[PackageRequiresGetByPackageVersionIDRequiredTypeRequiredObjectMatch]
GO
CREATE PROCEDURE [dbo].[PackageRequiresGetByPackageVersionIDRequiredTypeRequiredObjectMatch]
	@PackageVersionID	int,
	@RequiredType		char(8),
	@RequiredObject		nvarchar(64),
	@Match			int
AS
	SELECT	PackageVersionID,
		RequiredType,
		RequiredObject,
		Strength,
		Property,
		Value,
		Match
	FROM	[dbo].[PackageRequires]
	WHERE	PackageVersionID = @PackageVersionID
	  AND	RequiredType = @RequiredType
	  AND	RequiredObject = @RequiredObject
	  AND	Match = @Match
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[PackageRequiresGetAll]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[PackageRequiresGetAll]
GO
CREATE PROCEDURE [dbo].[PackageRequiresGetAll]
AS
	SELECT	PackageVersionID,
		RequiredType,
		RequiredObject,
		Strength,
		Property,
		Value,
		Match
	FROM	[dbo].[PackageRequires]
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[PackageRequiresAdd]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[PackageRequiresAdd]
GO
CREATE PROCEDURE [dbo].[PackageRequiresAdd]
	@PackageVersionID	int,
	@RequiredType		char(8),
	@RequiredObject		nvarchar(64),
	@Strength		int = NULL,
	@Property		nvarchar(64) = 'Version',
	@Value			nvarchar(64) = NULL,
	@Match			int
AS
	INSERT INTO  dbo.PackageRequires (
		PackageVersionID,
		RequiredType,
		RequiredObject,
		Strength,
		Property,
		Value,
		Match
	)
	VALUES (
		@PackageVersionID,
		@RequiredType,
		@RequiredObject,
		@Strength,
		@Property,
		@Value,
		@Match
	)
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[PackageRequiresSchema]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[PackageRequiresSchema]
GO
CREATE PROCEDURE [dbo].[PackageRequiresSchema]
AS
	SELECT
	'IF OBJECT_ID(''tempdb..#PackageRequires'') IS NULL' + CAST(0x0A AS CHAR(1)) +
	'	CREATE TABLE #PackageRequires (' + CAST(0x0A AS CHAR(1)) +
	'		PackageVersionID	int NOT NULL,' + CAST(0x0A AS CHAR(1)) +
	'		RequiredType		char(8) COLLATE database_default NOT NULL,' + CAST(0x0A AS CHAR(1)) +
	'		RequiredObject		nvarchar(64) COLLATE database_default NOT NULL,' + CAST(0x0A AS CHAR(1)) +
	'		Strength		int NULL,' + CAST(0x0A AS CHAR(1)) +
	'		Property		nvarchar(64) COLLATE database_default NULL DEFAULT ''Version'',' + CAST(0x0A AS CHAR(1)) +
	'		Value			nvarchar(64) COLLATE database_default NULL,' + CAST(0x0A AS CHAR(1)) +
	'		Match			int NOT NULL' + CAST(0x0A AS CHAR(1)) +
	'	)' + CAST(0x0A AS CHAR(1)) +
	'ELSE' + CAST(0x0A AS CHAR(1)) +
	'	DELETE FROM #PackageRequires' + CAST(0x0A AS CHAR(1)) +
	'' AS SQL
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[PackageRequiresTempAdd]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[PackageRequiresTempAdd]
GO
CREATE PROCEDURE dbo.[PackageRequiresTempAdd]
	@PackageVersionID	int,
	@RequiredType		char(8),
	@RequiredObject		nvarchar(64),
	@Strength		int = NULL,
	@Property		nvarchar(64) = 'Version',
	@Value			nvarchar(64) = NULL,
	@Match			int
AS
	INSERT INTO #PackageRequires (
		PackageVersionID,
		RequiredType,
		RequiredObject,
		Strength,
		Property,
		Value,
		Match
	)
	VALUES (
		@PackageVersionID,
		@RequiredType,
		@RequiredObject,
		@Strength,
		@Property,
		@Value,
		@Match
	)
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[PackageRequiresAddBatch]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[PackageRequiresAddBatch]
GO
CREATE PROCEDURE dbo.[PackageRequiresAddBatch]
AS
	DECLARE @count int
	INSERT dbo.PackageRequires (
		PackageVersionID,
		RequiredType,
		RequiredObject,
		Strength,
		Property,
		Value,
		Match
	)
		SELECT	PackageVersionID,
			RequiredType,
			RequiredObject,
			Strength,
			Property,
			Value,
			Match
		FROM #PackageRequires
	SET @count = @@ROWCOUNT
	DROP TABLE #PackageRequires	-- Drop temporary table
	RETURN @count
GO

/*
Add new PackageRequires bound to
	PackageVersion using PackagePathID, Version, Update with PackageFamilyID
	with RequiredType, RequiredObject, Strength, Property, Value, Match
*/

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[PackageRequiresUpdateByPackageVersionIDRequiredTypeRequiredObjectMatch]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[PackageRequiresUpdateByPackageVersionIDRequiredTypeRequiredObjectMatch]
GO
CREATE PROCEDURE [dbo].[PackageRequiresUpdateByPackageVersionIDRequiredTypeRequiredObjectMatch]
	@PackageVersionID	int,
	@RequiredType		char(8),
	@RequiredObject		nvarchar(64),
	@Match			int,
	@Strength		int = NULL,
	@Property		nvarchar(64) = 'Version',
	@Value			nvarchar(64) = NULL
AS
	UPDATE	[dbo].[PackageRequires]
	SET	Strength = @Strength,
		Property = @Property,
		Value = @Value
	WHERE	PackageVersionID = @PackageVersionID
	  AND	RequiredType = @RequiredType
	  AND	RequiredObject = @RequiredObject
	  AND	Match = @Match
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[PackageRequiresUpdateBatchByPackageVersionIDRequiredTypeRequiredObjectMatch]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[PackageRequiresUpdateBatchByPackageVersionIDRequiredTypeRequiredObjectMatch]
GO
CREATE PROCEDURE dbo.[PackageRequiresUpdateBatchByPackageVersionIDRequiredTypeRequiredObjectMatch]
AS
	DECLARE @count int

	CREATE INDEX [TempPackageRequiresPackageVersionIDRequiredTypeRequiredObjectMatch]
		ON #PackageRequires (PackageVersionID, RequiredType, RequiredObject, Match)

	UPDATE	[dbo].[PackageRequires]
	SET	Strength = t.Strength,
		Property = t.Property,
		Value = t.Value
	FROM	#PackageRequires AS t
	WHERE	PackageRequires.PackageVersionID = t.PackageVersionID
	  AND	PackageRequires.RequiredType = t.RequiredType
	  AND	PackageRequires.RequiredObject = t.RequiredObject
	  AND	PackageRequires.Match = t.Match
	SET @count = @@ROWCOUNT
	DROP TABLE #PackageRequires	-- Drop the temporary table
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[PackageRequiresPutByPackageVersionIDRequiredTypeRequiredObjectMatch]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[PackageRequiresPutByPackageVersionIDRequiredTypeRequiredObjectMatch]
GO
CREATE PROCEDURE [dbo].[PackageRequiresPutByPackageVersionIDRequiredTypeRequiredObjectMatch]
	@PackageVersionID	int,
	@RequiredType		char(8),
	@RequiredObject		nvarchar(64),
	@Match			int,
	@Strength		int = NULL,
	@Property		nvarchar(64) = 'Version',
	@Value			nvarchar(64) = NULL
AS
	IF NOT EXISTS(
		SELECT	1
		FROM	dbo.PackageRequires
		WHERE	PackageVersionID = @PackageVersionID
		  AND	RequiredType = @RequiredType
		  AND	RequiredObject = @RequiredObject
		  AND	Match = @Match
	)
		EXEC PackageRequiresAdd @PackageVersionID,
			@RequiredType,
			@RequiredObject,
			@Strength,
			@Property,
			@Value,
			@Match
	ELSE
		EXEC PackageRequiresUpdateByPackageVersionIDRequiredTypeRequiredObjectMatch @PackageVersionID,
			@RequiredType,
			@RequiredObject,
			@Match,
			@Strength,
			@Property,
			@Value
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[PackageRequiresPutBatchByPackageVersionIDRequiredTypeRequiredObjectMatch]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[PackageRequiresPutBatchByPackageVersionIDRequiredTypeRequiredObjectMatch]
GO
CREATE PROCEDURE [dbo].[PackageRequiresPutBatchByPackageVersionIDRequiredTypeRequiredObjectMatch]
AS
	DECLARE @count AS int
	SET @count = 0

	CREATE INDEX [TempPackageRequiresPackageVersionIDRequiredTypeRequiredObjectMatch]
		ON #PackageRequires (PackageVersionID, RequiredType, RequiredObject, Match)

	BEGIN TRANSACTION
	UPDATE [dbo].[PackageRequires]
		SET	Strength = t.Strength,
			Property = t.Property,
			Value = t.Value
		FROM	#PackageRequires AS t
		WHERE	PackageRequires.PackageVersionID = t.PackageVersionID
		  AND	PackageRequires.RequiredType = t.RequiredType
		  AND	PackageRequires.RequiredObject = t.RequiredObject
		  AND	PackageRequires.Match = t.Match
	SET @count = @@ROWCOUNT

	INSERT [dbo].[PackageRequires] (
		PackageVersionID,
		RequiredType,
		RequiredObject,
		Strength,
		Property,
		Value,
		Match
	)
		SELECT	PackageVersionID,
			RequiredType,
			RequiredObject,
			Strength,
			Property,
			Value,
			Match
		FROM	#PackageRequires AS t
		WHERE NOT EXISTS(	-- Current record doesn't exist
			SELECT * FROM [dbo].[PackageRequires]
			WHERE	PackageRequires.PackageVersionID = t.PackageVersionID
			  AND	PackageRequires.RequiredType = t.RequiredType
			  AND	PackageRequires.RequiredObject = t.RequiredObject
			  AND	PackageRequires.Match = t.Match
		)
	SET @count = @count + @@ROWCOUNT
	DROP TABLE #PackageRequires	-- Drop the temporary table
	COMMIT WORK
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[PackageRequiresRemoveBatch]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[PackageRequiresRemoveBatch]
GO

CREATE PROCEDURE [dbo].[PackageRequiresRemoveBatch]
AS

	CREATE INDEX [TempPackageRequiresPackageRequiresRemoveBatch]
		ON #PackageRequires (PackageVersionID, RequiredType, RequiredObject, Match)	

	-- Delete records from PackageRequires identified by fields of [TempPackageRequiresPackageRequiresRemoveBatch]
	DELETE [dbo].[PackageRequires]
	WHERE EXISTS(
			SELECT * FROM #PackageRequires AS t
			WHERE	PackageRequires.PackageVersionID = t.PackageVersionID
			  AND	PackageRequires.RequiredType = t.RequiredType
			  AND	PackageRequires.RequiredObject = t.RequiredObject
			  AND	PackageRequires.Match = t.Match
		)
	DROP TABLE #PackageRequires      -- Drop the temporary table
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[PackageRequiresRemoveByPackageVersionIDRequiredTypeRequiredObjectMatch]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[PackageRequiresRemoveByPackageVersionIDRequiredTypeRequiredObjectMatch]
GO
CREATE PROCEDURE [dbo].[PackageRequiresRemoveByPackageVersionIDRequiredTypeRequiredObjectMatch]
	@PackageVersionID	int,
	@RequiredType		char(8),
	@RequiredObject		nvarchar(64),
	@Match			int
AS
	DELETE	[dbo].[PackageRequires]
	WHERE	PackageVersionID = @PackageVersionID
	  AND	RequiredType = @RequiredType
	  AND	RequiredObject = @RequiredObject
	  AND	Match = @Match
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[PackageRequiresRemoveAllByPackageVersionID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[PackageRequiresRemoveAllByPackageVersionID]
GO
CREATE PROCEDURE [dbo].[PackageRequiresRemoveAllByPackageVersionID]
	@PackageVersionID	int
AS
	DELETE	[dbo].[PackageRequires]
	WHERE	PackageVersionID = @PackageVersionID
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[PackageRequiresRemoveAll]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[PackageRequiresRemoveAll]
GO
CREATE PROCEDURE [dbo].[PackageRequiresRemoveAll]
	
AS
	DELETE	[dbo].[PackageRequires]
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[MediaTypeGetByID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[MediaTypeGetByID]
GO
CREATE PROCEDURE [dbo].[MediaTypeGetByID]
	@MediaTypeID		int
AS
	SELECT	MediaTypeID,
		Description
	FROM	[dbo].[MediaType]
	WHERE	MediaTypeID = @MediaTypeID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[MediaTypeGetByDescription]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[MediaTypeGetByDescription]
GO
CREATE PROCEDURE [dbo].[MediaTypeGetByDescription]
	@Description		nvarchar(128)
AS
	SELECT	MediaTypeID,
		Description
	FROM	[dbo].[MediaType]
	WHERE	Description = @Description
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[MediaTypeGetAll]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[MediaTypeGetAll]
GO
CREATE PROCEDURE [dbo].[MediaTypeGetAll]
AS
	SELECT	MediaTypeID,
		Description
	FROM	[dbo].[MediaType]
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[MediaTypeBind]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[MediaTypeBind]
GO
CREATE PROCEDURE [dbo].[MediaTypeBind]
	@Description		nvarchar(128)
AS
	DECLARE	@ID	int

	SELECT	@ID = MediaTypeID
	FROM	[dbo].[MediaType]
	WHERE	Description = @Description

	RETURN @ID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[MediaGetByTitle]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[MediaGetByTitle]
GO
CREATE PROCEDURE [dbo].[MediaGetByTitle]
	@Title			nvarchar(128)
AS
	SELECT	MediaID,
		Title,
		MediaTypeID,
		Location
	FROM	[dbo].[Media]
	WHERE	Title = @Title
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[MediaGetAllByTypeID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[MediaGetAllByTypeID]
GO
CREATE PROCEDURE [dbo].[MediaGetAllByTypeID]
	@MediaTypeID		int
AS
	SELECT	MediaID,
		Title,
		MediaTypeID,
		Location
	FROM	[dbo].[Media]
	WHERE	MediaTypeID = @MediaTypeID
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[MediaGetAll]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[MediaGetAll]
GO
CREATE PROCEDURE [dbo].[MediaGetAll]
AS
	SELECT	MediaID,
		Title,
		MediaTypeID,
		Location
	FROM	[dbo].[Media]
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[MediaAdd]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[MediaAdd]
GO
CREATE PROCEDURE [dbo].[MediaAdd]
	@Title			nvarchar(128),
	@MediaTypeID		int,
	@Location		nvarchar(256) = NULL
AS
	INSERT INTO  dbo.Media (
		Title,
		MediaTypeID,
		Location
	)
	VALUES (
		@Title,
		@MediaTypeID,
		@Location
	)
	RETURN SCOPE_IDENTITY()
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[MediaBind]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[MediaBind]
GO
CREATE PROCEDURE [dbo].[MediaBind]
	@Title			nvarchar(128),
	@MediaTypeID		int,
	@Location		nvarchar(256) = NULL
AS
	DECLARE	@ID	int

	SELECT	@ID = MediaID
	FROM	[dbo].[Media]
	WHERE	Title = @Title

	IF @ID IS NULL
		EXEC @ID = MediaAdd @Title,
			@MediaTypeID,
			@Location

	RETURN @ID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[MediaSchema]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[MediaSchema]
GO
CREATE PROCEDURE [dbo].[MediaSchema]
AS
	SELECT
	'IF OBJECT_ID(''tempdb..#Media'') IS NULL' + CAST(0x0A AS CHAR(1)) +
	'	CREATE TABLE #Media (' + CAST(0x0A AS CHAR(1)) +
	'		MediaID			int NULL,' + CAST(0x0A AS CHAR(1)) +
	'		Title			nvarchar(128) COLLATE database_default NOT NULL,' + CAST(0x0A AS CHAR(1)) +
	'		MediaTypeID		int NOT NULL,' + CAST(0x0A AS CHAR(1)) +
	'		Location		nvarchar(256) COLLATE database_default NULL' + CAST(0x0A AS CHAR(1)) +
	'	)' + CAST(0x0A AS CHAR(1)) +
	'ELSE' + CAST(0x0A AS CHAR(1)) +
	'	DELETE FROM #Media' + CAST(0x0A AS CHAR(1)) +
	'' AS SQL
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[MediaTempAdd]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[MediaTempAdd]
GO
CREATE PROCEDURE dbo.[MediaTempAdd]
	@MediaID		int,
	@Title			nvarchar(128),
	@MediaTypeID		int,
	@Location		nvarchar(256) = NULL
AS
	INSERT INTO #Media (
		MediaID,
		Title,
		MediaTypeID,
		Location
	)
	VALUES (
		@MediaID,
		@Title,
		@MediaTypeID,
		@Location
	)
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[MediaAddBatch]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[MediaAddBatch]
GO
CREATE PROCEDURE dbo.[MediaAddBatch]
AS
	DECLARE @count int
	INSERT dbo.Media (
		Title,
		MediaTypeID,
		Location
	)
		SELECT	Title,
			MediaTypeID,
			Location
		FROM #Media
	SET @count = @@ROWCOUNT
	DROP TABLE #Media	-- Drop temporary table
	RETURN @count
GO

/*
Add new Media bound to
	MediaType using Description
	with Title, Location
*/

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[MediaUpdateByID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[MediaUpdateByID]
GO
CREATE PROCEDURE [dbo].[MediaUpdateByID]
	@MediaID		int,
	@Title			nvarchar(128),
	@MediaTypeID		int,
	@Location		nvarchar(256) = NULL
AS
	DECLARE	@ID	int
	SET @ID = 0

	UPDATE	[dbo].[Media]
	SET	@ID = MediaID,
		Title = @Title,
		MediaTypeID = @MediaTypeID,
		Location = @Location
	WHERE	MediaID = @MediaID
	RETURN @ID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[MediaUpdateBatchByID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[MediaUpdateBatchByID]
GO
CREATE PROCEDURE dbo.[MediaUpdateBatchByID]
AS
	DECLARE @count int

	CREATE INDEX [TempMediaID]
		ON #Media (MediaID)

	UPDATE	[dbo].[Media]
	SET	Title = t.Title,
		MediaTypeID = t.MediaTypeID,
		Location = t.Location
	FROM	#Media AS t
	WHERE	Media.MediaID = t.MediaID
	SET @count = @@ROWCOUNT
	DROP TABLE #Media	-- Drop the temporary table
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[MediaUpdateByTitle]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[MediaUpdateByTitle]
GO
CREATE PROCEDURE [dbo].[MediaUpdateByTitle]
	@Title			nvarchar(128),
	@MediaTypeID		int,
	@Location		nvarchar(256) = NULL
AS
	DECLARE	@ID	int
	SET @ID = 0

	UPDATE	[dbo].[Media]
	SET	@ID = MediaID,
		MediaTypeID = @MediaTypeID,
		Location = @Location
	WHERE	Title = @Title
	RETURN @ID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[MediaUpdateBatchByTitle]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[MediaUpdateBatchByTitle]
GO
CREATE PROCEDURE dbo.[MediaUpdateBatchByTitle]
AS
	DECLARE @count int

	CREATE INDEX [TempMediaTitle]
		ON #Media (Title)

	UPDATE	[dbo].[Media]
	SET	MediaTypeID = t.MediaTypeID,
		Location = t.Location
	FROM	#Media AS t
	WHERE	Media.Title = t.Title
	SET @count = @@ROWCOUNT
	DROP TABLE #Media	-- Drop the temporary table
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[MediaPutByTitle]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[MediaPutByTitle]
GO
CREATE PROCEDURE [dbo].[MediaPutByTitle]
	@Title			nvarchar(128),
	@MediaTypeID		int,
	@Location		nvarchar(256) = NULL
AS
	DECLARE @ID	int

	SELECT	@ID = MediaID
	FROM	Media
	WHERE	Title = @Title

	IF @ID IS NULL
		EXEC @ID = MediaAdd @Title,
			@MediaTypeID,
			@Location
	ELSE
		EXEC MediaUpdateByTitle @Title,
			@MediaTypeID,
			@Location

	RETURN @ID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[MediaPutBatchByTitle]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[MediaPutBatchByTitle]
GO
CREATE PROCEDURE [dbo].[MediaPutBatchByTitle]
AS
	DECLARE @count AS int
	SET @count = 0

	CREATE INDEX [TempMediaTitle]
		ON #Media (Title)

	BEGIN TRANSACTION
	UPDATE [dbo].[Media]
		SET	MediaTypeID = t.MediaTypeID,
			Location = t.Location
		FROM	#Media AS t
		WHERE	Media.Title = t.Title
	SET @count = @@ROWCOUNT

	INSERT [dbo].[Media] (
		Title,
		MediaTypeID,
		Location
	)
		SELECT	Title,
			MediaTypeID,
			Location
		FROM	#Media AS t
		WHERE NOT EXISTS(	-- Current record doesn't exist
			SELECT * FROM [dbo].[Media]
			WHERE	Media.Title = t.Title
		)
	SET @count = @count + @@ROWCOUNT
	DROP TABLE #Media	-- Drop the temporary table
	COMMIT WORK
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[MediaRemoveBatch]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[MediaRemoveBatch]
GO

CREATE PROCEDURE [dbo].[MediaRemoveBatch]
AS

	CREATE INDEX [TempMediaMediaRemoveBatch]
		ON #Media (MediaID)	

	-- Delete records from Media identified by fields of [TempMediaMediaRemoveBatch]
	DELETE [dbo].[Media]
	WHERE EXISTS(
			SELECT * FROM #Media AS t
			WHERE	Media.MediaID = t.MediaID
		)
	DROP TABLE #Media      -- Drop the temporary table
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[MediaRemoveByID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[MediaRemoveByID]
GO
CREATE PROCEDURE [dbo].[MediaRemoveByID]
	@MediaID		int
AS
	-- Media deletes cascade to:
	--	MediaContainsPackageVersion by FK_MCPV_MediaID
	--	MediaContainsPackagePath by FK_MCPP_Media
	--	FileNameMap by FK_FileNameMap_Media
	DELETE	[dbo].[Media]
	WHERE	MediaID = @MediaID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[MediaRemoveByTitle]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[MediaRemoveByTitle]
GO
CREATE PROCEDURE [dbo].[MediaRemoveByTitle]
	@Title			nvarchar(128)
AS
	-- Media deletes cascade to:
	--	MediaContainsPackageVersion by FK_MCPV_MediaID
	--	MediaContainsPackagePath by FK_MCPP_Media
	--	FileNameMap by FK_FileNameMap_Media
	DELETE	[dbo].[Media]
	WHERE	Title = @Title
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[MediaRemoveAll]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[MediaRemoveAll]
GO
CREATE PROCEDURE [dbo].[MediaRemoveAll]
	
AS
	DELETE	[dbo].[Media]
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[MediaContainsPackageVersionGetByMediaIDPackageVersionID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[MediaContainsPackageVersionGetByMediaIDPackageVersionID]
GO
CREATE PROCEDURE [dbo].[MediaContainsPackageVersionGetByMediaIDPackageVersionID]
	@MediaID		int,
	@PackageVersionID	int
AS
	SELECT	MediaID,
		PackageVersionID
	FROM	[dbo].[MediaContainsPackageVersion]
	WHERE	MediaID = @MediaID
	  AND	PackageVersionID = @PackageVersionID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[MediaContainsPackageVersionGetAllByMediaID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[MediaContainsPackageVersionGetAllByMediaID]
GO
CREATE PROCEDURE [dbo].[MediaContainsPackageVersionGetAllByMediaID]
	@MediaID		int
AS
	SELECT	MediaID,
		PackageVersionID
	FROM	[dbo].[MediaContainsPackageVersion]
	WHERE	MediaID = @MediaID
	ORDER BY PackageVersionID
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[MediaContainsPackageVersionGetAllByPackageVersionID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[MediaContainsPackageVersionGetAllByPackageVersionID]
GO
CREATE PROCEDURE [dbo].[MediaContainsPackageVersionGetAllByPackageVersionID]
	@PackageVersionID	int
AS
	SELECT	MediaID,
		PackageVersionID
	FROM	[dbo].[MediaContainsPackageVersion]
	WHERE	PackageVersionID = @PackageVersionID
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[MediaContainsPackageVersionGetAll]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[MediaContainsPackageVersionGetAll]
GO
CREATE PROCEDURE [dbo].[MediaContainsPackageVersionGetAll]
AS
	SELECT	MediaID,
		PackageVersionID
	FROM	[dbo].[MediaContainsPackageVersion]
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[MediaContainsPackageVersionAdd]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[MediaContainsPackageVersionAdd]
GO
CREATE PROCEDURE [dbo].[MediaContainsPackageVersionAdd]
	@MediaID		int,
	@PackageVersionID	int
AS
	INSERT INTO  dbo.MediaContainsPackageVersion (
		MediaID,
		PackageVersionID
	)
	VALUES (
		@MediaID,
		@PackageVersionID
	)
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[MediaContainsPackageVersionSchema]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[MediaContainsPackageVersionSchema]
GO
CREATE PROCEDURE [dbo].[MediaContainsPackageVersionSchema]
AS
	SELECT
	'IF OBJECT_ID(''tempdb..#MediaContainsPackageVersion'') IS NULL' + CAST(0x0A AS CHAR(1)) +
	'	CREATE TABLE #MediaContainsPackageVersion (' + CAST(0x0A AS CHAR(1)) +
	'		MediaID			int NOT NULL,' + CAST(0x0A AS CHAR(1)) +
	'		PackageVersionID	int NOT NULL' + CAST(0x0A AS CHAR(1)) +
	'	)' + CAST(0x0A AS CHAR(1)) +
	'ELSE' + CAST(0x0A AS CHAR(1)) +
	'	DELETE FROM #MediaContainsPackageVersion' + CAST(0x0A AS CHAR(1)) +
	'' AS SQL
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[MediaContainsPackageVersionTempAdd]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[MediaContainsPackageVersionTempAdd]
GO
CREATE PROCEDURE dbo.[MediaContainsPackageVersionTempAdd]
	@MediaID		int,
	@PackageVersionID	int
AS
	INSERT INTO #MediaContainsPackageVersion (
		MediaID,
		PackageVersionID
	)
	VALUES (
		@MediaID,
		@PackageVersionID
	)
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[MediaContainsPackageVersionAddBatch]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[MediaContainsPackageVersionAddBatch]
GO
CREATE PROCEDURE dbo.[MediaContainsPackageVersionAddBatch]
AS
	DECLARE @count int
	INSERT dbo.MediaContainsPackageVersion (
		MediaID,
		PackageVersionID
	)
		SELECT	MediaID,
			PackageVersionID
		FROM #MediaContainsPackageVersion
	SET @count = @@ROWCOUNT
	DROP TABLE #MediaContainsPackageVersion	-- Drop temporary table
	RETURN @count
GO

/*
Add new MediaContainsPackageVersion bound to
	Media using Title with MediaTypeID
	PackageVersion using PackagePathID, Version, Update with PackageFamilyID
	with 
*/

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[MediaContainsPackageVersionPutByMediaIDPackageVersionID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[MediaContainsPackageVersionPutByMediaIDPackageVersionID]
GO
CREATE PROCEDURE [dbo].[MediaContainsPackageVersionPutByMediaIDPackageVersionID]
	@MediaID		int,
	@PackageVersionID	int
AS
	IF NOT EXISTS(
		SELECT	1
		FROM	dbo.MediaContainsPackageVersion
		WHERE	MediaID = @MediaID
		  AND	PackageVersionID = @PackageVersionID
	)
		EXEC MediaContainsPackageVersionAdd @MediaID,
			@PackageVersionID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[MediaContainsPackageVersionPutBatchByMediaIDPackageVersionID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[MediaContainsPackageVersionPutBatchByMediaIDPackageVersionID]
GO
CREATE PROCEDURE [dbo].[MediaContainsPackageVersionPutBatchByMediaIDPackageVersionID]
AS
	DECLARE @count AS int
	SET @count = 0

	CREATE INDEX [TempMediaContainsPackageVersionMediaIDPackageVersionID]
		ON #MediaContainsPackageVersion (MediaID, PackageVersionID)

	BEGIN TRANSACTION

	INSERT [dbo].[MediaContainsPackageVersion] (
		MediaID,
		PackageVersionID
	)
		SELECT	MediaID,
			PackageVersionID
		FROM	#MediaContainsPackageVersion AS t
		WHERE NOT EXISTS(	-- Current record doesn't exist
			SELECT * FROM [dbo].[MediaContainsPackageVersion]
			WHERE	MediaContainsPackageVersion.MediaID = t.MediaID
			  AND	MediaContainsPackageVersion.PackageVersionID = t.PackageVersionID
		)
	SET @count = @count + @@ROWCOUNT
	DROP TABLE #MediaContainsPackageVersion	-- Drop the temporary table
	COMMIT WORK
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[MediaContainsPackageVersionRemoveBatch]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[MediaContainsPackageVersionRemoveBatch]
GO

CREATE PROCEDURE [dbo].[MediaContainsPackageVersionRemoveBatch]
AS

	CREATE INDEX [TempMediaContainsPackageVersionMediaContainsPackageVersionRemoveBatch]
		ON #MediaContainsPackageVersion (MediaID, PackageVersionID)	

	-- Delete records from MediaContainsPackageVersion identified by fields of [TempMediaContainsPackageVersionMediaContainsPackageVersionRemoveBatch]
	DELETE [dbo].[MediaContainsPackageVersion]
	WHERE EXISTS(
			SELECT * FROM #MediaContainsPackageVersion AS t
			WHERE	MediaContainsPackageVersion.MediaID = t.MediaID
			  AND	MediaContainsPackageVersion.PackageVersionID = t.PackageVersionID
		)
	DROP TABLE #MediaContainsPackageVersion      -- Drop the temporary table
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[MediaContainsPackageVersionRemoveByMediaIDPackageVersionID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[MediaContainsPackageVersionRemoveByMediaIDPackageVersionID]
GO
CREATE PROCEDURE [dbo].[MediaContainsPackageVersionRemoveByMediaIDPackageVersionID]
	@MediaID		int,
	@PackageVersionID	int
AS
	DELETE	[dbo].[MediaContainsPackageVersion]
	WHERE	MediaID = @MediaID
	  AND	PackageVersionID = @PackageVersionID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[MediaContainsPackageVersionRemoveAllByPackageVersionID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[MediaContainsPackageVersionRemoveAllByPackageVersionID]
GO
CREATE PROCEDURE [dbo].[MediaContainsPackageVersionRemoveAllByPackageVersionID]
	@PackageVersionID	int
AS
	DELETE	[dbo].[MediaContainsPackageVersion]
	WHERE	PackageVersionID = @PackageVersionID
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[MediaContainsPackageVersionRemoveAll]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[MediaContainsPackageVersionRemoveAll]
GO
CREATE PROCEDURE [dbo].[MediaContainsPackageVersionRemoveAll]
	
AS
	DELETE	[dbo].[MediaContainsPackageVersion]
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[MediaContainsPackagePathGetByMediaIDPackagePathID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[MediaContainsPackagePathGetByMediaIDPackagePathID]
GO
CREATE PROCEDURE [dbo].[MediaContainsPackagePathGetByMediaIDPackagePathID]
	@MediaID		int,
	@PackagePathID		int
AS
	SELECT	MediaID,
		PackagePathID
	FROM	[dbo].[MediaContainsPackagePath]
	WHERE	MediaID = @MediaID
	  AND	PackagePathID = @PackagePathID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[MediaContainsPackagePathGetAllByMediaID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[MediaContainsPackagePathGetAllByMediaID]
GO
CREATE PROCEDURE [dbo].[MediaContainsPackagePathGetAllByMediaID]
	@MediaID		int
AS
	SELECT	MediaID,
		PackagePathID
	FROM	[dbo].[MediaContainsPackagePath]
	WHERE	MediaID = @MediaID
	ORDER BY PackagePathID
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[MediaContainsPackagePathGetAll]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[MediaContainsPackagePathGetAll]
GO
CREATE PROCEDURE [dbo].[MediaContainsPackagePathGetAll]
AS
	SELECT	MediaID,
		PackagePathID
	FROM	[dbo].[MediaContainsPackagePath]
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[MediaContainsPackagePathAdd]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[MediaContainsPackagePathAdd]
GO
CREATE PROCEDURE [dbo].[MediaContainsPackagePathAdd]
	@MediaID		int,
	@PackagePathID		int
AS
	INSERT INTO  dbo.MediaContainsPackagePath (
		MediaID,
		PackagePathID
	)
	VALUES (
		@MediaID,
		@PackagePathID
	)
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[MediaContainsPackagePathSchema]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[MediaContainsPackagePathSchema]
GO
CREATE PROCEDURE [dbo].[MediaContainsPackagePathSchema]
AS
	SELECT
	'IF OBJECT_ID(''tempdb..#MediaContainsPackagePath'') IS NULL' + CAST(0x0A AS CHAR(1)) +
	'	CREATE TABLE #MediaContainsPackagePath (' + CAST(0x0A AS CHAR(1)) +
	'		MediaID			int NOT NULL,' + CAST(0x0A AS CHAR(1)) +
	'		PackagePathID		int NOT NULL' + CAST(0x0A AS CHAR(1)) +
	'	)' + CAST(0x0A AS CHAR(1)) +
	'ELSE' + CAST(0x0A AS CHAR(1)) +
	'	DELETE FROM #MediaContainsPackagePath' + CAST(0x0A AS CHAR(1)) +
	'' AS SQL
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[MediaContainsPackagePathTempAdd]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[MediaContainsPackagePathTempAdd]
GO
CREATE PROCEDURE dbo.[MediaContainsPackagePathTempAdd]
	@MediaID		int,
	@PackagePathID		int
AS
	INSERT INTO #MediaContainsPackagePath (
		MediaID,
		PackagePathID
	)
	VALUES (
		@MediaID,
		@PackagePathID
	)
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[MediaContainsPackagePathAddBatch]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[MediaContainsPackagePathAddBatch]
GO
CREATE PROCEDURE dbo.[MediaContainsPackagePathAddBatch]
AS
	DECLARE @count int
	INSERT dbo.MediaContainsPackagePath (
		MediaID,
		PackagePathID
	)
		SELECT	MediaID,
			PackagePathID
		FROM #MediaContainsPackagePath
	SET @count = @@ROWCOUNT
	DROP TABLE #MediaContainsPackagePath	-- Drop temporary table
	RETURN @count
GO

/*
Add new MediaContainsPackagePath bound to
	Media using Title with MediaTypeID
	with PackagePathID
*/

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[MediaContainsPackagePathPutByMediaIDPackagePathID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[MediaContainsPackagePathPutByMediaIDPackagePathID]
GO
CREATE PROCEDURE [dbo].[MediaContainsPackagePathPutByMediaIDPackagePathID]
	@MediaID		int,
	@PackagePathID		int
AS
	IF NOT EXISTS(
		SELECT	1
		FROM	dbo.MediaContainsPackagePath
		WHERE	MediaID = @MediaID
		  AND	PackagePathID = @PackagePathID
	)
		EXEC MediaContainsPackagePathAdd @MediaID,
			@PackagePathID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[MediaContainsPackagePathPutBatchByMediaIDPackagePathID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[MediaContainsPackagePathPutBatchByMediaIDPackagePathID]
GO
CREATE PROCEDURE [dbo].[MediaContainsPackagePathPutBatchByMediaIDPackagePathID]
AS
	DECLARE @count AS int
	SET @count = 0

	CREATE INDEX [TempMediaContainsPackagePathMediaIDPackagePathID]
		ON #MediaContainsPackagePath (MediaID, PackagePathID)

	BEGIN TRANSACTION

	INSERT [dbo].[MediaContainsPackagePath] (
		MediaID,
		PackagePathID
	)
		SELECT	MediaID,
			PackagePathID
		FROM	#MediaContainsPackagePath AS t
		WHERE NOT EXISTS(	-- Current record doesn't exist
			SELECT * FROM [dbo].[MediaContainsPackagePath]
			WHERE	MediaContainsPackagePath.MediaID = t.MediaID
			  AND	MediaContainsPackagePath.PackagePathID = t.PackagePathID
		)
	SET @count = @count + @@ROWCOUNT
	DROP TABLE #MediaContainsPackagePath	-- Drop the temporary table
	COMMIT WORK
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[MediaContainsPackagePathRemoveBatch]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[MediaContainsPackagePathRemoveBatch]
GO

CREATE PROCEDURE [dbo].[MediaContainsPackagePathRemoveBatch]
AS

	CREATE INDEX [TempMediaContainsPackagePathMediaContainsPackagePathRemoveBatch]
		ON #MediaContainsPackagePath (MediaID, PackagePathID)	

	-- Delete records from MediaContainsPackagePath identified by fields of [TempMediaContainsPackagePathMediaContainsPackagePathRemoveBatch]
	DELETE [dbo].[MediaContainsPackagePath]
	WHERE EXISTS(
			SELECT * FROM #MediaContainsPackagePath AS t
			WHERE	MediaContainsPackagePath.MediaID = t.MediaID
			  AND	MediaContainsPackagePath.PackagePathID = t.PackagePathID
		)
	DROP TABLE #MediaContainsPackagePath      -- Drop the temporary table
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[MediaContainsPackagePathRemoveByMediaIDPackagePathID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[MediaContainsPackagePathRemoveByMediaIDPackagePathID]
GO
CREATE PROCEDURE [dbo].[MediaContainsPackagePathRemoveByMediaIDPackagePathID]
	@MediaID		int,
	@PackagePathID		int
AS
	DELETE	[dbo].[MediaContainsPackagePath]
	WHERE	MediaID = @MediaID
	  AND	PackagePathID = @PackagePathID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[MediaContainsPackagePathRemoveAll]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[MediaContainsPackagePathRemoveAll]
GO
CREATE PROCEDURE [dbo].[MediaContainsPackagePathRemoveAll]
	
AS
	DELETE	[dbo].[MediaContainsPackagePath]
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[PackageVersionLocaleGetByPackageVersionIDLocaleCode]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[PackageVersionLocaleGetByPackageVersionIDLocaleCode]
GO
CREATE PROCEDURE [dbo].[PackageVersionLocaleGetByPackageVersionIDLocaleCode]
	@PackageVersionID	int,
	@LocaleCode		nvarchar(6)
AS
	SELECT	PackageVersionID,
		LocaleCode
	FROM	[dbo].[PackageVersionLocale]
	WHERE	PackageVersionID = @PackageVersionID
	  AND	LocaleCode = @LocaleCode
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[PackageVersionLocaleGetAll]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[PackageVersionLocaleGetAll]
GO
CREATE PROCEDURE [dbo].[PackageVersionLocaleGetAll]
AS
	SELECT	PackageVersionID,
		LocaleCode
	FROM	[dbo].[PackageVersionLocale]
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[PackageVersionLocaleAdd]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[PackageVersionLocaleAdd]
GO
CREATE PROCEDURE [dbo].[PackageVersionLocaleAdd]
	@PackageVersionID	int,
	@LocaleCode		nvarchar(6)
AS
	INSERT INTO  dbo.PackageVersionLocale (
		PackageVersionID,
		LocaleCode
	)
	VALUES (
		@PackageVersionID,
		@LocaleCode
	)
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[PackageVersionLocaleSchema]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[PackageVersionLocaleSchema]
GO
CREATE PROCEDURE [dbo].[PackageVersionLocaleSchema]
AS
	SELECT
	'IF OBJECT_ID(''tempdb..#PackageVersionLocale'') IS NULL' + CAST(0x0A AS CHAR(1)) +
	'	CREATE TABLE #PackageVersionLocale (' + CAST(0x0A AS CHAR(1)) +
	'		PackageVersionID	int NOT NULL,' + CAST(0x0A AS CHAR(1)) +
	'		LocaleCode		nvarchar(6) COLLATE database_default NOT NULL' + CAST(0x0A AS CHAR(1)) +
	'	)' + CAST(0x0A AS CHAR(1)) +
	'ELSE' + CAST(0x0A AS CHAR(1)) +
	'	DELETE FROM #PackageVersionLocale' + CAST(0x0A AS CHAR(1)) +
	'' AS SQL
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[PackageVersionLocaleTempAdd]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[PackageVersionLocaleTempAdd]
GO
CREATE PROCEDURE dbo.[PackageVersionLocaleTempAdd]
	@PackageVersionID	int,
	@LocaleCode		nvarchar(6)
AS
	INSERT INTO #PackageVersionLocale (
		PackageVersionID,
		LocaleCode
	)
	VALUES (
		@PackageVersionID,
		@LocaleCode
	)
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[PackageVersionLocaleAddBatch]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[PackageVersionLocaleAddBatch]
GO
CREATE PROCEDURE dbo.[PackageVersionLocaleAddBatch]
AS
	DECLARE @count int
	INSERT dbo.PackageVersionLocale (
		PackageVersionID,
		LocaleCode
	)
		SELECT	PackageVersionID,
			LocaleCode
		FROM #PackageVersionLocale
	SET @count = @@ROWCOUNT
	DROP TABLE #PackageVersionLocale	-- Drop temporary table
	RETURN @count
GO

/*
Add new PackageVersionLocale bound to
	PackageVersion using PackagePathID, Version, Update with PackageFamilyID
	with LocaleCode
*/

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[PackageVersionLocalePutByPackageVersionIDLocaleCode]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[PackageVersionLocalePutByPackageVersionIDLocaleCode]
GO
CREATE PROCEDURE [dbo].[PackageVersionLocalePutByPackageVersionIDLocaleCode]
	@PackageVersionID	int,
	@LocaleCode		nvarchar(6)
AS
	IF NOT EXISTS(
		SELECT	1
		FROM	dbo.PackageVersionLocale
		WHERE	PackageVersionID = @PackageVersionID
		  AND	LocaleCode = @LocaleCode
	)
		EXEC PackageVersionLocaleAdd @PackageVersionID,
			@LocaleCode
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[PackageVersionLocalePutBatchByPackageVersionIDLocaleCode]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[PackageVersionLocalePutBatchByPackageVersionIDLocaleCode]
GO
CREATE PROCEDURE [dbo].[PackageVersionLocalePutBatchByPackageVersionIDLocaleCode]
AS
	DECLARE @count AS int
	SET @count = 0

	CREATE INDEX [TempPackageVersionLocalePackageVersionIDLocaleCode]
		ON #PackageVersionLocale (PackageVersionID, LocaleCode)

	BEGIN TRANSACTION

	INSERT [dbo].[PackageVersionLocale] (
		PackageVersionID,
		LocaleCode
	)
		SELECT	PackageVersionID,
			LocaleCode
		FROM	#PackageVersionLocale AS t
		WHERE NOT EXISTS(	-- Current record doesn't exist
			SELECT * FROM [dbo].[PackageVersionLocale]
			WHERE	PackageVersionLocale.PackageVersionID = t.PackageVersionID
			  AND	PackageVersionLocale.LocaleCode = t.LocaleCode
		)
	SET @count = @count + @@ROWCOUNT
	DROP TABLE #PackageVersionLocale	-- Drop the temporary table
	COMMIT WORK
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[PackageVersionLocaleRemoveBatch]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[PackageVersionLocaleRemoveBatch]
GO

CREATE PROCEDURE [dbo].[PackageVersionLocaleRemoveBatch]
AS

	CREATE INDEX [TempPackageVersionLocalePackageVersionLocaleRemoveBatch]
		ON #PackageVersionLocale (PackageVersionID, LocaleCode)	

	-- Delete records from PackageVersionLocale identified by fields of [TempPackageVersionLocalePackageVersionLocaleRemoveBatch]
	DELETE [dbo].[PackageVersionLocale]
	WHERE EXISTS(
			SELECT * FROM #PackageVersionLocale AS t
			WHERE	PackageVersionLocale.PackageVersionID = t.PackageVersionID
			  AND	PackageVersionLocale.LocaleCode = t.LocaleCode
		)
	DROP TABLE #PackageVersionLocale      -- Drop the temporary table
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[PackageVersionLocaleRemoveByPackageVersionIDLocaleCode]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[PackageVersionLocaleRemoveByPackageVersionIDLocaleCode]
GO
CREATE PROCEDURE [dbo].[PackageVersionLocaleRemoveByPackageVersionIDLocaleCode]
	@PackageVersionID	int,
	@LocaleCode		nvarchar(6)
AS
	DELETE	[dbo].[PackageVersionLocale]
	WHERE	PackageVersionID = @PackageVersionID
	  AND	LocaleCode = @LocaleCode
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[PackageVersionLocaleRemoveAllByPackageVersionID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[PackageVersionLocaleRemoveAllByPackageVersionID]
GO
CREATE PROCEDURE [dbo].[PackageVersionLocaleRemoveAllByPackageVersionID]
	@PackageVersionID	int
AS
	DELETE	[dbo].[PackageVersionLocale]
	WHERE	PackageVersionID = @PackageVersionID
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[PackageVersionLocaleRemoveAll]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[PackageVersionLocaleRemoveAll]
GO
CREATE PROCEDURE [dbo].[PackageVersionLocaleRemoveAll]
	
AS
	DELETE	[dbo].[PackageVersionLocale]
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[PackageVersionArchitectureGetByPackageVersionIDArchitectureID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[PackageVersionArchitectureGetByPackageVersionIDArchitectureID]
GO
CREATE PROCEDURE [dbo].[PackageVersionArchitectureGetByPackageVersionIDArchitectureID]
	@PackageVersionID	int,
	@ArchitectureID		int
AS
	SELECT	PackageVersionID,
		ArchitectureID
	FROM	[dbo].[PackageVersionArchitecture]
	WHERE	PackageVersionID = @PackageVersionID
	  AND	ArchitectureID = @ArchitectureID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[PackageVersionArchitectureGetAll]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[PackageVersionArchitectureGetAll]
GO
CREATE PROCEDURE [dbo].[PackageVersionArchitectureGetAll]
AS
	SELECT	PackageVersionID,
		ArchitectureID
	FROM	[dbo].[PackageVersionArchitecture]
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[PackageVersionArchitectureAdd]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[PackageVersionArchitectureAdd]
GO
CREATE PROCEDURE [dbo].[PackageVersionArchitectureAdd]
	@PackageVersionID	int,
	@ArchitectureID		int
AS
	INSERT INTO  dbo.PackageVersionArchitecture (
		PackageVersionID,
		ArchitectureID
	)
	VALUES (
		@PackageVersionID,
		@ArchitectureID
	)
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[PackageVersionArchitectureSchema]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[PackageVersionArchitectureSchema]
GO
CREATE PROCEDURE [dbo].[PackageVersionArchitectureSchema]
AS
	SELECT
	'IF OBJECT_ID(''tempdb..#PackageVersionArchitecture'') IS NULL' + CAST(0x0A AS CHAR(1)) +
	'	CREATE TABLE #PackageVersionArchitecture (' + CAST(0x0A AS CHAR(1)) +
	'		PackageVersionID	int NOT NULL,' + CAST(0x0A AS CHAR(1)) +
	'		ArchitectureID		int NOT NULL' + CAST(0x0A AS CHAR(1)) +
	'	)' + CAST(0x0A AS CHAR(1)) +
	'ELSE' + CAST(0x0A AS CHAR(1)) +
	'	DELETE FROM #PackageVersionArchitecture' + CAST(0x0A AS CHAR(1)) +
	'' AS SQL
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[PackageVersionArchitectureTempAdd]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[PackageVersionArchitectureTempAdd]
GO
CREATE PROCEDURE dbo.[PackageVersionArchitectureTempAdd]
	@PackageVersionID	int,
	@ArchitectureID		int
AS
	INSERT INTO #PackageVersionArchitecture (
		PackageVersionID,
		ArchitectureID
	)
	VALUES (
		@PackageVersionID,
		@ArchitectureID
	)
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[PackageVersionArchitectureAddBatch]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[PackageVersionArchitectureAddBatch]
GO
CREATE PROCEDURE dbo.[PackageVersionArchitectureAddBatch]
AS
	DECLARE @count int
	INSERT dbo.PackageVersionArchitecture (
		PackageVersionID,
		ArchitectureID
	)
		SELECT	PackageVersionID,
			ArchitectureID
		FROM #PackageVersionArchitecture
	SET @count = @@ROWCOUNT
	DROP TABLE #PackageVersionArchitecture	-- Drop temporary table
	RETURN @count
GO

/*
Add new PackageVersionArchitecture bound to
	PackageVersion using PackagePathID, Version, Update with PackageFamilyID
	Architecture using ArchitectureName
	with 
*/

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[PackageVersionArchitecturePutByPackageVersionIDArchitectureID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[PackageVersionArchitecturePutByPackageVersionIDArchitectureID]
GO
CREATE PROCEDURE [dbo].[PackageVersionArchitecturePutByPackageVersionIDArchitectureID]
	@PackageVersionID	int,
	@ArchitectureID		int
AS
	IF NOT EXISTS(
		SELECT	1
		FROM	dbo.PackageVersionArchitecture
		WHERE	PackageVersionID = @PackageVersionID
		  AND	ArchitectureID = @ArchitectureID
	)
		EXEC PackageVersionArchitectureAdd @PackageVersionID,
			@ArchitectureID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[PackageVersionArchitecturePutBatchByPackageVersionIDArchitectureID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[PackageVersionArchitecturePutBatchByPackageVersionIDArchitectureID]
GO
CREATE PROCEDURE [dbo].[PackageVersionArchitecturePutBatchByPackageVersionIDArchitectureID]
AS
	DECLARE @count AS int
	SET @count = 0

	CREATE INDEX [TempPackageVersionArchitecturePackageVersionIDArchitectureID]
		ON #PackageVersionArchitecture (PackageVersionID, ArchitectureID)

	BEGIN TRANSACTION

	INSERT [dbo].[PackageVersionArchitecture] (
		PackageVersionID,
		ArchitectureID
	)
		SELECT	PackageVersionID,
			ArchitectureID
		FROM	#PackageVersionArchitecture AS t
		WHERE NOT EXISTS(	-- Current record doesn't exist
			SELECT * FROM [dbo].[PackageVersionArchitecture]
			WHERE	PackageVersionArchitecture.PackageVersionID = t.PackageVersionID
			  AND	PackageVersionArchitecture.ArchitectureID = t.ArchitectureID
		)
	SET @count = @count + @@ROWCOUNT
	DROP TABLE #PackageVersionArchitecture	-- Drop the temporary table
	COMMIT WORK
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[PackageVersionArchitectureRemoveBatch]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[PackageVersionArchitectureRemoveBatch]
GO

CREATE PROCEDURE [dbo].[PackageVersionArchitectureRemoveBatch]
AS

	CREATE INDEX [TempPackageVersionArchitecturePackageVersionArchitectureRemoveBatch]
		ON #PackageVersionArchitecture (PackageVersionID, ArchitectureID)	

	-- Delete records from PackageVersionArchitecture identified by fields of [TempPackageVersionArchitecturePackageVersionArchitectureRemoveBatch]
	DELETE [dbo].[PackageVersionArchitecture]
	WHERE EXISTS(
			SELECT * FROM #PackageVersionArchitecture AS t
			WHERE	PackageVersionArchitecture.PackageVersionID = t.PackageVersionID
			  AND	PackageVersionArchitecture.ArchitectureID = t.ArchitectureID
		)
	DROP TABLE #PackageVersionArchitecture      -- Drop the temporary table
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[PackageVersionArchitectureRemoveByPackageVersionIDArchitectureID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[PackageVersionArchitectureRemoveByPackageVersionIDArchitectureID]
GO
CREATE PROCEDURE [dbo].[PackageVersionArchitectureRemoveByPackageVersionIDArchitectureID]
	@PackageVersionID	int,
	@ArchitectureID		int
AS
	DELETE	[dbo].[PackageVersionArchitecture]
	WHERE	PackageVersionID = @PackageVersionID
	  AND	ArchitectureID = @ArchitectureID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[PackageVersionArchitectureRemoveAllByPackageVersionID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[PackageVersionArchitectureRemoveAllByPackageVersionID]
GO
CREATE PROCEDURE [dbo].[PackageVersionArchitectureRemoveAllByPackageVersionID]
	@PackageVersionID	int
AS
	DELETE	[dbo].[PackageVersionArchitecture]
	WHERE	PackageVersionID = @PackageVersionID
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[PackageVersionArchitectureRemoveAll]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[PackageVersionArchitectureRemoveAll]
GO
CREATE PROCEDURE [dbo].[PackageVersionArchitectureRemoveAll]
	
AS
	DELETE	[dbo].[PackageVersionArchitecture]
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[PackageVersionEnvironmentGetByPackageVersionIDEnvironment]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[PackageVersionEnvironmentGetByPackageVersionIDEnvironment]
GO
CREATE PROCEDURE [dbo].[PackageVersionEnvironmentGetByPackageVersionIDEnvironment]
	@PackageVersionID	int,
	@Environment		nvarchar(128)
AS
	SELECT	PackageVersionID,
		Environment
	FROM	[dbo].[PackageVersionEnvironment]
	WHERE	PackageVersionID = @PackageVersionID
	  AND	Environment = @Environment
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[PackageVersionEnvironmentGetAll]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[PackageVersionEnvironmentGetAll]
GO
CREATE PROCEDURE [dbo].[PackageVersionEnvironmentGetAll]
AS
	SELECT	PackageVersionID,
		Environment
	FROM	[dbo].[PackageVersionEnvironment]
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[PackageVersionEnvironmentAdd]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[PackageVersionEnvironmentAdd]
GO
CREATE PROCEDURE [dbo].[PackageVersionEnvironmentAdd]
	@PackageVersionID	int,
	@Environment		nvarchar(128)
AS
	INSERT INTO  dbo.PackageVersionEnvironment (
		PackageVersionID,
		Environment
	)
	VALUES (
		@PackageVersionID,
		@Environment
	)
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[PackageVersionEnvironmentSchema]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[PackageVersionEnvironmentSchema]
GO
CREATE PROCEDURE [dbo].[PackageVersionEnvironmentSchema]
AS
	SELECT
	'IF OBJECT_ID(''tempdb..#PackageVersionEnvironment'') IS NULL' + CAST(0x0A AS CHAR(1)) +
	'	CREATE TABLE #PackageVersionEnvironment (' + CAST(0x0A AS CHAR(1)) +
	'		PackageVersionID	int NOT NULL,' + CAST(0x0A AS CHAR(1)) +
	'		Environment		nvarchar(128) COLLATE database_default NOT NULL' + CAST(0x0A AS CHAR(1)) +
	'	)' + CAST(0x0A AS CHAR(1)) +
	'ELSE' + CAST(0x0A AS CHAR(1)) +
	'	DELETE FROM #PackageVersionEnvironment' + CAST(0x0A AS CHAR(1)) +
	'' AS SQL
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[PackageVersionEnvironmentTempAdd]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[PackageVersionEnvironmentTempAdd]
GO
CREATE PROCEDURE dbo.[PackageVersionEnvironmentTempAdd]
	@PackageVersionID	int,
	@Environment		nvarchar(128)
AS
	INSERT INTO #PackageVersionEnvironment (
		PackageVersionID,
		Environment
	)
	VALUES (
		@PackageVersionID,
		@Environment
	)
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[PackageVersionEnvironmentAddBatch]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[PackageVersionEnvironmentAddBatch]
GO
CREATE PROCEDURE dbo.[PackageVersionEnvironmentAddBatch]
AS
	DECLARE @count int
	INSERT dbo.PackageVersionEnvironment (
		PackageVersionID,
		Environment
	)
		SELECT	PackageVersionID,
			Environment
		FROM #PackageVersionEnvironment
	SET @count = @@ROWCOUNT
	DROP TABLE #PackageVersionEnvironment	-- Drop temporary table
	RETURN @count
GO

/*
Add new PackageVersionEnvironment bound to
	PackageVersion using PackagePathID, Version, Update with PackageFamilyID
	with Environment
*/

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[PackageVersionEnvironmentPutByPackageVersionIDEnvironment]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[PackageVersionEnvironmentPutByPackageVersionIDEnvironment]
GO
CREATE PROCEDURE [dbo].[PackageVersionEnvironmentPutByPackageVersionIDEnvironment]
	@PackageVersionID	int,
	@Environment		nvarchar(128)
AS
	IF NOT EXISTS(
		SELECT	1
		FROM	dbo.PackageVersionEnvironment
		WHERE	PackageVersionID = @PackageVersionID
		  AND	Environment = @Environment
	)
		EXEC PackageVersionEnvironmentAdd @PackageVersionID,
			@Environment
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[PackageVersionEnvironmentPutBatchByPackageVersionIDEnvironment]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[PackageVersionEnvironmentPutBatchByPackageVersionIDEnvironment]
GO
CREATE PROCEDURE [dbo].[PackageVersionEnvironmentPutBatchByPackageVersionIDEnvironment]
AS
	DECLARE @count AS int
	SET @count = 0

	CREATE INDEX [TempPackageVersionEnvironmentPackageVersionIDEnvironment]
		ON #PackageVersionEnvironment (PackageVersionID, Environment)

	BEGIN TRANSACTION

	INSERT [dbo].[PackageVersionEnvironment] (
		PackageVersionID,
		Environment
	)
		SELECT	PackageVersionID,
			Environment
		FROM	#PackageVersionEnvironment AS t
		WHERE NOT EXISTS(	-- Current record doesn't exist
			SELECT * FROM [dbo].[PackageVersionEnvironment]
			WHERE	PackageVersionEnvironment.PackageVersionID = t.PackageVersionID
			  AND	PackageVersionEnvironment.Environment = t.Environment
		)
	SET @count = @count + @@ROWCOUNT
	DROP TABLE #PackageVersionEnvironment	-- Drop the temporary table
	COMMIT WORK
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[PackageVersionEnvironmentRemoveBatch]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[PackageVersionEnvironmentRemoveBatch]
GO

CREATE PROCEDURE [dbo].[PackageVersionEnvironmentRemoveBatch]
AS

	CREATE INDEX [TempPackageVersionEnvironmentPackageVersionEnvironmentRemoveBatch]
		ON #PackageVersionEnvironment (PackageVersionID, Environment)	

	-- Delete records from PackageVersionEnvironment identified by fields of [TempPackageVersionEnvironmentPackageVersionEnvironmentRemoveBatch]
	DELETE [dbo].[PackageVersionEnvironment]
	WHERE EXISTS(
			SELECT * FROM #PackageVersionEnvironment AS t
			WHERE	PackageVersionEnvironment.PackageVersionID = t.PackageVersionID
			  AND	PackageVersionEnvironment.Environment = t.Environment
		)
	DROP TABLE #PackageVersionEnvironment      -- Drop the temporary table
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[PackageVersionEnvironmentRemoveByPackageVersionIDEnvironment]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[PackageVersionEnvironmentRemoveByPackageVersionIDEnvironment]
GO
CREATE PROCEDURE [dbo].[PackageVersionEnvironmentRemoveByPackageVersionIDEnvironment]
	@PackageVersionID	int,
	@Environment		nvarchar(128)
AS
	DELETE	[dbo].[PackageVersionEnvironment]
	WHERE	PackageVersionID = @PackageVersionID
	  AND	Environment = @Environment
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[PackageVersionEnvironmentRemoveAllByPackageVersionID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[PackageVersionEnvironmentRemoveAllByPackageVersionID]
GO
CREATE PROCEDURE [dbo].[PackageVersionEnvironmentRemoveAllByPackageVersionID]
	@PackageVersionID	int
AS
	DELETE	[dbo].[PackageVersionEnvironment]
	WHERE	PackageVersionID = @PackageVersionID
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[PackageVersionEnvironmentRemoveAll]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[PackageVersionEnvironmentRemoveAll]
GO
CREATE PROCEDURE [dbo].[PackageVersionEnvironmentRemoveAll]
	
AS
	DELETE	[dbo].[PackageVersionEnvironment]
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[FileNameMapGetByMediaIDSourceFile]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[FileNameMapGetByMediaIDSourceFile]
GO
CREATE PROCEDURE [dbo].[FileNameMapGetByMediaIDSourceFile]
	@MediaID		int,
	@SourceFile		nvarchar(256)
AS
	SELECT	MediaID,
		SourceFile,
		DestFile,
		IsFile
	FROM	[dbo].[FileNameMap]
	WHERE	MediaID = @MediaID
	  AND	SourceFile = @SourceFile
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[FileNameMapGetAll]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[FileNameMapGetAll]
GO
CREATE PROCEDURE [dbo].[FileNameMapGetAll]
AS
	SELECT	MediaID,
		SourceFile,
		DestFile,
		IsFile
	FROM	[dbo].[FileNameMap]
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[FileNameMapAdd]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[FileNameMapAdd]
GO
CREATE PROCEDURE [dbo].[FileNameMapAdd]
	@MediaID		int,
	@SourceFile		nvarchar(256),
	@DestFile		nvarchar(256),
	@IsFile			bit = 1
AS
	INSERT INTO  dbo.FileNameMap (
		MediaID,
		SourceFile,
		DestFile,
		IsFile
	)
	VALUES (
		@MediaID,
		@SourceFile,
		@DestFile,
		@IsFile
	)
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[FileNameMapSchema]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[FileNameMapSchema]
GO
CREATE PROCEDURE [dbo].[FileNameMapSchema]
AS
	SELECT
	'IF OBJECT_ID(''tempdb..#FileNameMap'') IS NULL' + CAST(0x0A AS CHAR(1)) +
	'	CREATE TABLE #FileNameMap (' + CAST(0x0A AS CHAR(1)) +
	'		MediaID			int NOT NULL,' + CAST(0x0A AS CHAR(1)) +
	'		SourceFile		nvarchar(256) COLLATE database_default NOT NULL,' + CAST(0x0A AS CHAR(1)) +
	'		DestFile		nvarchar(256) COLLATE database_default NOT NULL,' + CAST(0x0A AS CHAR(1)) +
	'		IsFile			bit NOT NULL DEFAULT 1' + CAST(0x0A AS CHAR(1)) +
	'	)' + CAST(0x0A AS CHAR(1)) +
	'ELSE' + CAST(0x0A AS CHAR(1)) +
	'	DELETE FROM #FileNameMap' + CAST(0x0A AS CHAR(1)) +
	'' AS SQL
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[FileNameMapTempAdd]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[FileNameMapTempAdd]
GO
CREATE PROCEDURE dbo.[FileNameMapTempAdd]
	@MediaID		int,
	@SourceFile		nvarchar(256),
	@DestFile		nvarchar(256),
	@IsFile			bit = 1
AS
	INSERT INTO #FileNameMap (
		MediaID,
		SourceFile,
		DestFile,
		IsFile
	)
	VALUES (
		@MediaID,
		@SourceFile,
		@DestFile,
		@IsFile
	)
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[FileNameMapAddBatch]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[FileNameMapAddBatch]
GO
CREATE PROCEDURE dbo.[FileNameMapAddBatch]
AS
	DECLARE @count int
	INSERT dbo.FileNameMap (
		MediaID,
		SourceFile,
		DestFile,
		IsFile
	)
		SELECT	MediaID,
			SourceFile,
			DestFile,
			IsFile
		FROM #FileNameMap
	SET @count = @@ROWCOUNT
	DROP TABLE #FileNameMap	-- Drop temporary table
	RETURN @count
GO

/*
Add new FileNameMap bound to
	Media using Title with MediaTypeID
	with SourceFile, DestFile, IsFile
*/

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[FileNameMapUpdateByMediaIDSourceFile]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[FileNameMapUpdateByMediaIDSourceFile]
GO
CREATE PROCEDURE [dbo].[FileNameMapUpdateByMediaIDSourceFile]
	@MediaID		int,
	@SourceFile		nvarchar(256),
	@DestFile		nvarchar(256),
	@IsFile			bit = 1
AS
	UPDATE	[dbo].[FileNameMap]
	SET	DestFile = @DestFile,
		IsFile = @IsFile
	WHERE	MediaID = @MediaID
	  AND	SourceFile = @SourceFile
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[FileNameMapUpdateBatchByMediaIDSourceFile]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[FileNameMapUpdateBatchByMediaIDSourceFile]
GO
CREATE PROCEDURE dbo.[FileNameMapUpdateBatchByMediaIDSourceFile]
AS
	DECLARE @count int

	CREATE INDEX [TempFileNameMapMediaIDSourceFile]
		ON #FileNameMap (MediaID, SourceFile)

	UPDATE	[dbo].[FileNameMap]
	SET	DestFile = t.DestFile,
		IsFile = t.IsFile
	FROM	#FileNameMap AS t
	WHERE	FileNameMap.MediaID = t.MediaID
	  AND	FileNameMap.SourceFile = t.SourceFile
	SET @count = @@ROWCOUNT
	DROP TABLE #FileNameMap	-- Drop the temporary table
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[FileNameMapPutByMediaIDSourceFile]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[FileNameMapPutByMediaIDSourceFile]
GO
CREATE PROCEDURE [dbo].[FileNameMapPutByMediaIDSourceFile]
	@MediaID		int,
	@SourceFile		nvarchar(256),
	@DestFile		nvarchar(256),
	@IsFile			bit = 1
AS
	IF NOT EXISTS(
		SELECT	1
		FROM	dbo.FileNameMap
		WHERE	MediaID = @MediaID
		  AND	SourceFile = @SourceFile
	)
		EXEC FileNameMapAdd @MediaID,
			@SourceFile,
			@DestFile,
			@IsFile
	ELSE
		EXEC FileNameMapUpdateByMediaIDSourceFile @MediaID,
			@SourceFile,
			@DestFile,
			@IsFile
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[FileNameMapPutBatchByMediaIDSourceFile]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[FileNameMapPutBatchByMediaIDSourceFile]
GO
CREATE PROCEDURE [dbo].[FileNameMapPutBatchByMediaIDSourceFile]
AS
	DECLARE @count AS int
	SET @count = 0

	CREATE INDEX [TempFileNameMapMediaIDSourceFile]
		ON #FileNameMap (MediaID, SourceFile)

	BEGIN TRANSACTION
	UPDATE [dbo].[FileNameMap]
		SET	DestFile = t.DestFile,
			IsFile = t.IsFile
		FROM	#FileNameMap AS t
		WHERE	FileNameMap.MediaID = t.MediaID
		  AND	FileNameMap.SourceFile = t.SourceFile
	SET @count = @@ROWCOUNT

	INSERT [dbo].[FileNameMap] (
		MediaID,
		SourceFile,
		DestFile,
		IsFile
	)
		SELECT	MediaID,
			SourceFile,
			DestFile,
			IsFile
		FROM	#FileNameMap AS t
		WHERE NOT EXISTS(	-- Current record doesn't exist
			SELECT * FROM [dbo].[FileNameMap]
			WHERE	FileNameMap.MediaID = t.MediaID
			  AND	FileNameMap.SourceFile = t.SourceFile
		)
	SET @count = @count + @@ROWCOUNT
	DROP TABLE #FileNameMap	-- Drop the temporary table
	COMMIT WORK
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[FileNameMapRemoveBatch]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[FileNameMapRemoveBatch]
GO

CREATE PROCEDURE [dbo].[FileNameMapRemoveBatch]
AS

	CREATE INDEX [TempFileNameMapFileNameMapRemoveBatch]
		ON #FileNameMap (MediaID, SourceFile)	

	-- Delete records from FileNameMap identified by fields of [TempFileNameMapFileNameMapRemoveBatch]
	DELETE [dbo].[FileNameMap]
	WHERE EXISTS(
			SELECT * FROM #FileNameMap AS t
			WHERE	FileNameMap.MediaID = t.MediaID
			  AND	FileNameMap.SourceFile = t.SourceFile
		)
	DROP TABLE #FileNameMap      -- Drop the temporary table
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[FileNameMapRemoveByMediaIDSourceFile]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[FileNameMapRemoveByMediaIDSourceFile]
GO
CREATE PROCEDURE [dbo].[FileNameMapRemoveByMediaIDSourceFile]
	@MediaID		int,
	@SourceFile		nvarchar(256)
AS
	DELETE	[dbo].[FileNameMap]
	WHERE	MediaID = @MediaID
	  AND	SourceFile = @SourceFile
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[FileNameMapRemoveAllByMediaID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[FileNameMapRemoveAllByMediaID]
GO
CREATE PROCEDURE [dbo].[FileNameMapRemoveAllByMediaID]
	@MediaID		int
AS
	DELETE	[dbo].[FileNameMap]
	WHERE	MediaID = @MediaID
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[FileNameMapRemoveAll]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[FileNameMapRemoveAll]
GO
CREATE PROCEDURE [dbo].[FileNameMapRemoveAll]
	
AS
	DELETE	[dbo].[FileNameMap]
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ReasonGetByID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ReasonGetByID]
GO
CREATE PROCEDURE [dbo].[ReasonGetByID]
	@ReasonID		int
AS
	SELECT	ReasonID,
		ReasonHash,
		ReasonText
	FROM	[dbo].[Reason]
	WHERE	ReasonID = @ReasonID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ReasonGetByHash]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ReasonGetByHash]
GO
CREATE PROCEDURE [dbo].[ReasonGetByHash]
	@ReasonHash		int
AS
	SELECT	ReasonID,
		ReasonHash,
		ReasonText
	FROM	[dbo].[Reason]
	WHERE	ReasonHash = @ReasonHash
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ReasonGetAll]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ReasonGetAll]
GO
CREATE PROCEDURE [dbo].[ReasonGetAll]
AS
	SELECT	ReasonID,
		ReasonHash,
		ReasonText
	FROM	[dbo].[Reason]
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ReasonAdd]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ReasonAdd]
GO
CREATE PROCEDURE [dbo].[ReasonAdd]
	@ReasonText		ntext
AS
	INSERT INTO  dbo.Reason (
		ReasonText
	)
	VALUES (
		@ReasonText
	)
	RETURN SCOPE_IDENTITY()
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ReasonSchema]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ReasonSchema]
GO
CREATE PROCEDURE [dbo].[ReasonSchema]
AS
	SELECT
	'IF OBJECT_ID(''tempdb..#Reason'') IS NULL' + CAST(0x0A AS CHAR(1)) +
	'	CREATE TABLE #Reason (' + CAST(0x0A AS CHAR(1)) +
	'		ReasonID		int NULL,' + CAST(0x0A AS CHAR(1)) +
	'		ReasonText		ntext COLLATE database_default NOT NULL' + CAST(0x0A AS CHAR(1)) +
	'	)' + CAST(0x0A AS CHAR(1)) +
	'ELSE' + CAST(0x0A AS CHAR(1)) +
	'	DELETE FROM #Reason' + CAST(0x0A AS CHAR(1)) +
	'' AS SQL
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ReasonTempAdd]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ReasonTempAdd]
GO
CREATE PROCEDURE dbo.[ReasonTempAdd]
	@ReasonID		int,
	@ReasonText		ntext
AS
	INSERT INTO #Reason (
		ReasonID,
		ReasonText
	)
	VALUES (
		@ReasonID,
		@ReasonText
	)
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ReasonAddBatch]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ReasonAddBatch]
GO
CREATE PROCEDURE dbo.[ReasonAddBatch]
AS
	DECLARE @count int
	INSERT dbo.Reason (
		ReasonText
	)
		SELECT	ReasonText
		FROM #Reason
	SET @count = @@ROWCOUNT
	DROP TABLE #Reason	-- Drop temporary table
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ReasonUpdateByID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ReasonUpdateByID]
GO
CREATE PROCEDURE [dbo].[ReasonUpdateByID]
	@ReasonID		int,
	@ReasonText		ntext
AS
	DECLARE	@ID	int
	SET @ID = 0

	UPDATE	[dbo].[Reason]
	SET	@ID = ReasonID,
		ReasonText = @ReasonText
	WHERE	ReasonID = @ReasonID
	RETURN @ID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ReasonUpdateBatchByID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ReasonUpdateBatchByID]
GO
CREATE PROCEDURE dbo.[ReasonUpdateBatchByID]
AS
	DECLARE @count int

	CREATE INDEX [TempReasonID]
		ON #Reason (ReasonID)

	UPDATE	[dbo].[Reason]
	SET	ReasonText = t.ReasonText
	FROM	#Reason AS t
	WHERE	Reason.ReasonID = t.ReasonID
	SET @count = @@ROWCOUNT
	DROP TABLE #Reason	-- Drop the temporary table
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ReasonUpdateByHash]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ReasonUpdateByHash]
GO
CREATE PROCEDURE [dbo].[ReasonUpdateByHash]
	@ReasonHash		int,
	@ReasonText		ntext
AS
	DECLARE	@ID	int
	SET @ID = 0

	UPDATE	[dbo].[Reason]
	SET	@ID = ReasonID,
		ReasonText = @ReasonText
	WHERE	ReasonHash = @ReasonHash
	RETURN @ID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ReasonUpdateBatchByHash]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ReasonUpdateBatchByHash]
GO
CREATE PROCEDURE dbo.[ReasonUpdateBatchByHash]
AS
	DECLARE @count int

	CREATE INDEX [TempReasonHash]
		ON #Reason (ReasonHash)

	UPDATE	[dbo].[Reason]
	SET	ReasonText = t.ReasonText
	FROM	#Reason AS t
	WHERE	Reason.ReasonHash = t.ReasonHash
	SET @count = @@ROWCOUNT
	DROP TABLE #Reason	-- Drop the temporary table
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ReasonRemoveBatch]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ReasonRemoveBatch]
GO

CREATE PROCEDURE [dbo].[ReasonRemoveBatch]
AS

	CREATE INDEX [TempReasonReasonRemoveBatch]
		ON #Reason (ReasonID)	

	-- Delete records from Reason identified by fields of [TempReasonReasonRemoveBatch]
	DELETE [dbo].[Reason]
	WHERE EXISTS(
			SELECT * FROM #Reason AS t
			WHERE	Reason.ReasonID = t.ReasonID
		)
	DROP TABLE #Reason      -- Drop the temporary table
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ReasonRemoveByHash]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ReasonRemoveByHash]
GO
CREATE PROCEDURE [dbo].[ReasonRemoveByHash]
	@ReasonHash		int
AS
	-- Reason deletes may fail due to non-cascading FKs:
	--	Installation by FK_Installation_Reason
	--	InstallationHistory by FK_InstallationHistory_Reason
	DELETE	[dbo].[Reason]
	WHERE	ReasonHash = @ReasonHash
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ReasonRemoveAll]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ReasonRemoveAll]
GO
CREATE PROCEDURE [dbo].[ReasonRemoveAll]
	
AS
	DELETE	[dbo].[Reason]
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[InstallationGetAllByComputerIDUserID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[InstallationGetAllByComputerIDUserID]
GO
CREATE PROCEDURE [dbo].[InstallationGetAllByComputerIDUserID]
	@ComputerID		int,
	@UserID			int
AS
	SELECT	ComputerID,
		UserID,
		PackageVersionID,
		OrganizationID,
		Action,
		Reported,
		Received,
		FailReasonID,
		Result
	FROM	[dbo].[Installation]
	WHERE	ComputerID = @ComputerID
	  AND	UserID = @UserID
	ORDER BY PackageVersionID
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[InstallationGetAll]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[InstallationGetAll]
GO
CREATE PROCEDURE [dbo].[InstallationGetAll]
AS
	SELECT	ComputerID,
		UserID,
		PackageVersionID,
		OrganizationID,
		Action,
		Reported,
		Received,
		FailReasonID,
		Result
	FROM	[dbo].[Installation]
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[InstallationAdd]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[InstallationAdd]
GO
CREATE PROCEDURE [dbo].[InstallationAdd]
	@ComputerID		int,
	@UserID			int,
	@PackageVersionID	int,
	@OrganizationID		int,
	@Action			varchar(10),
	@Reported		datetime = NULL,
	@Received		datetime,
	@FailReasonID		int = NULL,
	@Result			varchar(16) = NULL
AS
	INSERT INTO  dbo.Installation (
		ComputerID,
		UserID,
		PackageVersionID,
		OrganizationID,
		Action,
		Reported,
		Received,
		FailReasonID,
		Result
	)
	VALUES (
		@ComputerID,
		@UserID,
		@PackageVersionID,
		@OrganizationID,
		@Action,
		@Reported,
		@Received,
		@FailReasonID,
		@Result
	)
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[InstallationSchema]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[InstallationSchema]
GO
CREATE PROCEDURE [dbo].[InstallationSchema]
AS
	SELECT
	'IF OBJECT_ID(''tempdb..#Installation'') IS NULL' + CAST(0x0A AS CHAR(1)) +
	'	CREATE TABLE #Installation (' + CAST(0x0A AS CHAR(1)) +
	'		ComputerID		int NOT NULL,' + CAST(0x0A AS CHAR(1)) +
	'		UserID			int NOT NULL,' + CAST(0x0A AS CHAR(1)) +
	'		PackageVersionID	int NOT NULL,' + CAST(0x0A AS CHAR(1)) +
	'		OrganizationID		int NOT NULL,' + CAST(0x0A AS CHAR(1)) +
	'		Action			varchar(10) COLLATE database_default NOT NULL,' + CAST(0x0A AS CHAR(1)) +
	'		Reported		datetime NULL,' + CAST(0x0A AS CHAR(1)) +
	'		Received		datetime NULL DEFAULT getdate(),' + CAST(0x0A AS CHAR(1)) +
	'		FailReasonID		int NULL,' + CAST(0x0A AS CHAR(1)) +
	'		Result			varchar(16) COLLATE database_default NULL' + CAST(0x0A AS CHAR(1)) +
	'	)' + CAST(0x0A AS CHAR(1)) +
	'ELSE' + CAST(0x0A AS CHAR(1)) +
	'	DELETE FROM #Installation' + CAST(0x0A AS CHAR(1)) +
	'' AS SQL
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[InstallationTempAdd]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[InstallationTempAdd]
GO
CREATE PROCEDURE dbo.[InstallationTempAdd]
	@ComputerID		int,
	@UserID			int,
	@PackageVersionID	int,
	@OrganizationID		int,
	@Action			varchar(10),
	@Reported		datetime = NULL,
	@Received		datetime,
	@FailReasonID		int = NULL,
	@Result			varchar(16) = NULL
AS
	INSERT INTO #Installation (
		ComputerID,
		UserID,
		PackageVersionID,
		OrganizationID,
		Action,
		Reported,
		Received,
		FailReasonID,
		Result
	)
	VALUES (
		@ComputerID,
		@UserID,
		@PackageVersionID,
		@OrganizationID,
		@Action,
		@Reported,
		@Received,
		@FailReasonID,
		@Result
	)
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[InstallationAddBatch]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[InstallationAddBatch]
GO
CREATE PROCEDURE dbo.[InstallationAddBatch]
AS
	DECLARE @count int
	INSERT dbo.Installation (
		ComputerID,
		UserID,
		PackageVersionID,
		OrganizationID,
		Action,
		Reported,
		Received,
		FailReasonID,
		Result
	)
		SELECT	ComputerID,
			UserID,
			PackageVersionID,
			OrganizationID,
			Action,
			Reported,
			Received,
			FailReasonID,
			Result
		FROM #Installation
	SET @count = @@ROWCOUNT
	DROP TABLE #Installation	-- Drop temporary table
	RETURN @count
GO

/*
Add new Installation bound to
	Organization using DomainID, RDN
	PackageVersion using PackagePathID, Version, Update with PackageFamilyID
	User using UserOUID, UserCN
	Reason using ReasonHash with ReasonText
	with ComputerID, Action, Reported, Received, Result
*/

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[InstallationUpdateByComputerIDUserIDPackageVersionID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[InstallationUpdateByComputerIDUserIDPackageVersionID]
GO
CREATE PROCEDURE [dbo].[InstallationUpdateByComputerIDUserIDPackageVersionID]
	@ComputerID		int,
	@UserID			int,
	@PackageVersionID	int,
	@OrganizationID		int,
	@Action			varchar(10),
	@Reported		datetime = NULL,
	@Received		datetime,
	@FailReasonID		int = NULL,
	@Result			varchar(16) = NULL
AS
	UPDATE	[dbo].[Installation]
	SET	OrganizationID = @OrganizationID,
		Action = @Action,
		Reported = @Reported,
		Received = @Received,
		FailReasonID = @FailReasonID,
		Result = @Result
	WHERE	ComputerID = @ComputerID
	  AND	UserID = @UserID
	  AND	PackageVersionID = @PackageVersionID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[InstallationUpdateBatchByComputerIDUserIDPackageVersionID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[InstallationUpdateBatchByComputerIDUserIDPackageVersionID]
GO
CREATE PROCEDURE dbo.[InstallationUpdateBatchByComputerIDUserIDPackageVersionID]
AS
	DECLARE @count int

	CREATE INDEX [TempInstallationComputerIDUserIDPackageVersionID]
		ON #Installation (ComputerID, UserID, PackageVersionID)

	UPDATE	[dbo].[Installation]
	SET	OrganizationID = t.OrganizationID,
		Action = t.Action,
		Reported = t.Reported,
		Received = t.Received,
		FailReasonID = t.FailReasonID,
		Result = t.Result
	FROM	#Installation AS t
	WHERE	Installation.ComputerID = t.ComputerID
	  AND	Installation.UserID = t.UserID
	  AND	Installation.PackageVersionID = t.PackageVersionID
	SET @count = @@ROWCOUNT
	DROP TABLE #Installation	-- Drop the temporary table
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[InstallationPutByComputerIDUserIDPackageVersionID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[InstallationPutByComputerIDUserIDPackageVersionID]
GO
CREATE PROCEDURE [dbo].[InstallationPutByComputerIDUserIDPackageVersionID]
	@ComputerID		int,
	@UserID			int,
	@PackageVersionID	int,
	@OrganizationID		int,
	@Action			varchar(10),
	@Reported		datetime = NULL,
	@Received		datetime,
	@FailReasonID		int = NULL,
	@Result			varchar(16) = NULL
AS
	IF NOT EXISTS(
		SELECT	1
		FROM	dbo.Installation
		WHERE	ComputerID = @ComputerID
		  AND	UserID = @UserID
		  AND	PackageVersionID = @PackageVersionID
	)
		EXEC InstallationAdd @ComputerID,
			@UserID,
			@PackageVersionID,
			@OrganizationID,
			@Action,
			@Reported,
			@Received,
			@FailReasonID,
			@Result
	ELSE
		EXEC InstallationUpdateByComputerIDUserIDPackageVersionID @ComputerID,
			@UserID,
			@PackageVersionID,
			@OrganizationID,
			@Action,
			@Reported,
			@Received,
			@FailReasonID,
			@Result
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[InstallationPutBatchByComputerIDUserIDPackageVersionID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[InstallationPutBatchByComputerIDUserIDPackageVersionID]
GO
CREATE PROCEDURE [dbo].[InstallationPutBatchByComputerIDUserIDPackageVersionID]
AS
	DECLARE @count AS int
	SET @count = 0

	CREATE INDEX [TempInstallationComputerIDUserIDPackageVersionID]
		ON #Installation (ComputerID, UserID, PackageVersionID)

	BEGIN TRANSACTION
	UPDATE [dbo].[Installation]
		SET	OrganizationID = t.OrganizationID,
			Action = t.Action,
			Reported = t.Reported,
			Received = t.Received,
			FailReasonID = t.FailReasonID,
			Result = t.Result
		FROM	#Installation AS t
		WHERE	Installation.ComputerID = t.ComputerID
		  AND	Installation.UserID = t.UserID
		  AND	Installation.PackageVersionID = t.PackageVersionID
	SET @count = @@ROWCOUNT

	INSERT [dbo].[Installation] (
		ComputerID,
		UserID,
		PackageVersionID,
		OrganizationID,
		Action,
		Reported,
		Received,
		FailReasonID,
		Result
	)
		SELECT	ComputerID,
			UserID,
			PackageVersionID,
			OrganizationID,
			Action,
			Reported,
			Received,
			FailReasonID,
			Result
		FROM	#Installation AS t
		WHERE NOT EXISTS(	-- Current record doesn't exist
			SELECT * FROM [dbo].[Installation]
			WHERE	Installation.ComputerID = t.ComputerID
			  AND	Installation.UserID = t.UserID
			  AND	Installation.PackageVersionID = t.PackageVersionID
		)
	SET @count = @count + @@ROWCOUNT
	DROP TABLE #Installation	-- Drop the temporary table
	COMMIT WORK
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[InstallationRemoveBatch]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[InstallationRemoveBatch]
GO

CREATE PROCEDURE [dbo].[InstallationRemoveBatch]
AS

	CREATE INDEX [TempInstallationInstallationRemoveBatch]
		ON #Installation (ComputerID, UserID, PackageVersionID)	

	-- Delete records from Installation identified by fields of [TempInstallationInstallationRemoveBatch]
	DELETE [dbo].[Installation]
	WHERE EXISTS(
			SELECT * FROM #Installation AS t
			WHERE	Installation.ComputerID = t.ComputerID
			  AND	Installation.UserID = t.UserID
			  AND	Installation.PackageVersionID = t.PackageVersionID
		)
	DROP TABLE #Installation      -- Drop the temporary table
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[InstallationRemoveByComputerIDUserIDPackageVersionID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[InstallationRemoveByComputerIDUserIDPackageVersionID]
GO
CREATE PROCEDURE [dbo].[InstallationRemoveByComputerIDUserIDPackageVersionID]
	@ComputerID		int,
	@UserID			int,
	@PackageVersionID	int
AS
	DELETE	[dbo].[Installation]
	WHERE	ComputerID = @ComputerID
	  AND	UserID = @UserID
	  AND	PackageVersionID = @PackageVersionID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[InstallationRemoveAllByComputerIDUserID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[InstallationRemoveAllByComputerIDUserID]
GO
CREATE PROCEDURE [dbo].[InstallationRemoveAllByComputerIDUserID]
	@ComputerID		int,
	@UserID			int
AS
	DELETE	[dbo].[Installation]
	WHERE	ComputerID = @ComputerID
	  AND	UserID = @UserID
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[InstallationRemoveAll]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[InstallationRemoveAll]
GO
CREATE PROCEDURE [dbo].[InstallationRemoveAll]
	
AS
	DELETE	[dbo].[Installation]
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[InstallationReplaceSubsetByComputerIDUserID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[InstallationReplaceSubsetByComputerIDUserID]
GO
-- Replace the record subset selected by (@ComputerID, @UserID)
-- using unique identifier (ComputerID, UserID, PackageVersionID)
-- updating fields (OrganizationID, Action, Reported, Received, FailReasonID, Result)
CREATE PROCEDURE [dbo].[InstallationReplaceSubsetByComputerIDUserID]
	@ComputerID		int,
	@UserID			int
AS
	DECLARE @count AS int
	SET @count = 0

	CREATE INDEX [TempInstallationByComputerIDUserID]
		ON #Installation (ComputerID, UserID, PackageVersionID)

	BEGIN TRANSACTION
	DELETE [Installation]
		WHERE	ComputerID = @ComputerID
		  AND	UserID = @UserID
		AND NOT EXISTS(		-- Replacement record doesn't exist
			SELECT * FROM #Installation AS t
			WHERE	Installation.ComputerID = t.ComputerID
			  AND	Installation.UserID = t.UserID
			  AND	Installation.PackageVersionID = t.PackageVersionID
		)

	UPDATE [dbo].[Installation]
		SET	OrganizationID = t.OrganizationID,
			Action = t.Action,
			Reported = t.Reported,
			Received = t.Received,
			FailReasonID = t.FailReasonID,
			Result = t.Result
		FROM	#Installation AS t
		WHERE	Installation.ComputerID = t.ComputerID
		  AND	Installation.UserID = t.UserID
		  AND	Installation.PackageVersionID = t.PackageVersionID
	SET @count = @@ROWCOUNT

	INSERT [Installation] (
		ComputerID,
		UserID,
		PackageVersionID,
		OrganizationID,
		Action,
		Reported,
		Received,
		FailReasonID,
		Result
	)
		SELECT	ComputerID,
			UserID,
			PackageVersionID,
			OrganizationID,
			Action,
			Reported,
			Received,
			FailReasonID,
			Result
		FROM	#Installation AS t
		WHERE NOT EXISTS(	-- Current record doesn't exist
			SELECT * FROM [Installation]
			WHERE	Installation.ComputerID = t.ComputerID
			  AND	Installation.UserID = t.UserID
			  AND	Installation.PackageVersionID = t.PackageVersionID
		)
	SET @count = @count + @@ROWCOUNT
	DROP TABLE #Installation	-- Drop the temporary table
	COMMIT WORK
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[InstallationHistoryGetAllByComputerIDUserIDPackageVersionID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[InstallationHistoryGetAllByComputerIDUserIDPackageVersionID]
GO
CREATE PROCEDURE [dbo].[InstallationHistoryGetAllByComputerIDUserIDPackageVersionID]
	@ComputerID		int,
	@UserID			int,
	@PackageVersionID	int
AS
	SELECT	ComputerID,
		UserID,
		PackageVersionID,
		Reported,
		Action,
		Received,
		FailReasonID,
		Result
	FROM	[dbo].[InstallationHistory]
	WHERE	ComputerID = @ComputerID
	  AND	UserID = @UserID
	  AND	PackageVersionID = @PackageVersionID
	ORDER BY Reported
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[InstallationHistoryGetAll]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[InstallationHistoryGetAll]
GO
CREATE PROCEDURE [dbo].[InstallationHistoryGetAll]
AS
	SELECT	ComputerID,
		UserID,
		PackageVersionID,
		Reported,
		Action,
		Received,
		FailReasonID,
		Result
	FROM	[dbo].[InstallationHistory]
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[InstallationHistoryAdd]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[InstallationHistoryAdd]
GO
CREATE PROCEDURE [dbo].[InstallationHistoryAdd]
	@ComputerID		int,
	@UserID			int,
	@PackageVersionID	int,
	@Reported		datetime,
	@Action			varchar(10),
	@Received		datetime,
	@FailReasonID		int = NULL,
	@Result			varchar(16) = NULL
AS
	INSERT INTO  dbo.InstallationHistory (
		ComputerID,
		UserID,
		PackageVersionID,
		Reported,
		Action,
		Received,
		FailReasonID,
		Result
	)
	VALUES (
		@ComputerID,
		@UserID,
		@PackageVersionID,
		@Reported,
		@Action,
		@Received,
		@FailReasonID,
		@Result
	)
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[InstallationHistorySchema]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[InstallationHistorySchema]
GO
CREATE PROCEDURE [dbo].[InstallationHistorySchema]
AS
	SELECT
	'IF OBJECT_ID(''tempdb..#InstallationHistory'') IS NULL' + CAST(0x0A AS CHAR(1)) +
	'	CREATE TABLE #InstallationHistory (' + CAST(0x0A AS CHAR(1)) +
	'		ComputerID		int NOT NULL,' + CAST(0x0A AS CHAR(1)) +
	'		UserID			int NOT NULL,' + CAST(0x0A AS CHAR(1)) +
	'		PackageVersionID	int NOT NULL,' + CAST(0x0A AS CHAR(1)) +
	'		Reported		datetime NOT NULL,' + CAST(0x0A AS CHAR(1)) +
	'		Action			varchar(10) COLLATE database_default NOT NULL,' + CAST(0x0A AS CHAR(1)) +
	'		Received		datetime NULL DEFAULT getdate(),' + CAST(0x0A AS CHAR(1)) +
	'		FailReasonID		int NULL,' + CAST(0x0A AS CHAR(1)) +
	'		Result			varchar(16) COLLATE database_default NULL' + CAST(0x0A AS CHAR(1)) +
	'	)' + CAST(0x0A AS CHAR(1)) +
	'ELSE' + CAST(0x0A AS CHAR(1)) +
	'	DELETE FROM #InstallationHistory' + CAST(0x0A AS CHAR(1)) +
	'' AS SQL
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[InstallationHistoryTempAdd]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[InstallationHistoryTempAdd]
GO
CREATE PROCEDURE dbo.[InstallationHistoryTempAdd]
	@ComputerID		int,
	@UserID			int,
	@PackageVersionID	int,
	@Reported		datetime,
	@Action			varchar(10),
	@Received		datetime,
	@FailReasonID		int = NULL,
	@Result			varchar(16) = NULL
AS
	INSERT INTO #InstallationHistory (
		ComputerID,
		UserID,
		PackageVersionID,
		Reported,
		Action,
		Received,
		FailReasonID,
		Result
	)
	VALUES (
		@ComputerID,
		@UserID,
		@PackageVersionID,
		@Reported,
		@Action,
		@Received,
		@FailReasonID,
		@Result
	)
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[InstallationHistoryAddBatch]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[InstallationHistoryAddBatch]
GO
CREATE PROCEDURE dbo.[InstallationHistoryAddBatch]
AS
	DECLARE @count int
	INSERT dbo.InstallationHistory (
		ComputerID,
		UserID,
		PackageVersionID,
		Reported,
		Action,
		Received,
		FailReasonID,
		Result
	)
		SELECT	ComputerID,
			UserID,
			PackageVersionID,
			Reported,
			Action,
			Received,
			FailReasonID,
			Result
		FROM #InstallationHistory
	SET @count = @@ROWCOUNT
	DROP TABLE #InstallationHistory	-- Drop temporary table
	RETURN @count
GO

/*
Add new InstallationHistory bound to
	PackageVersion using PackagePathID, Version, Update with PackageFamilyID
	User using UserOUID, UserCN
	Reason using ReasonHash with ReasonText
	with ComputerID, Reported, Action, Received, Result
*/

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[InstallationHistoryUpdateByComputerIDUserIDPackageVersionIDReported]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[InstallationHistoryUpdateByComputerIDUserIDPackageVersionIDReported]
GO
CREATE PROCEDURE [dbo].[InstallationHistoryUpdateByComputerIDUserIDPackageVersionIDReported]
	@ComputerID		int,
	@UserID			int,
	@PackageVersionID	int,
	@Reported		datetime,
	@Action			varchar(10),
	@Received		datetime,
	@FailReasonID		int = NULL,
	@Result			varchar(16) = NULL
AS
	UPDATE	[dbo].[InstallationHistory]
	SET	Action = @Action,
		Received = @Received,
		FailReasonID = @FailReasonID,
		Result = @Result
	WHERE	ComputerID = @ComputerID
	  AND	UserID = @UserID
	  AND	PackageVersionID = @PackageVersionID
	  AND	Reported = @Reported
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[InstallationHistoryUpdateBatchByComputerIDUserIDPackageVersionIDReported]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[InstallationHistoryUpdateBatchByComputerIDUserIDPackageVersionIDReported]
GO
CREATE PROCEDURE dbo.[InstallationHistoryUpdateBatchByComputerIDUserIDPackageVersionIDReported]
AS
	DECLARE @count int

	CREATE INDEX [TempInstallationHistoryComputerIDUserIDPackageVersionIDReported]
		ON #InstallationHistory (ComputerID, UserID, PackageVersionID, Reported)

	UPDATE	[dbo].[InstallationHistory]
	SET	Action = t.Action,
		Received = t.Received,
		FailReasonID = t.FailReasonID,
		Result = t.Result
	FROM	#InstallationHistory AS t
	WHERE	InstallationHistory.ComputerID = t.ComputerID
	  AND	InstallationHistory.UserID = t.UserID
	  AND	InstallationHistory.PackageVersionID = t.PackageVersionID
	  AND	InstallationHistory.Reported = t.Reported
	SET @count = @@ROWCOUNT
	DROP TABLE #InstallationHistory	-- Drop the temporary table
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[InstallationHistoryPutByComputerIDUserIDPackageVersionIDReported]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[InstallationHistoryPutByComputerIDUserIDPackageVersionIDReported]
GO
CREATE PROCEDURE [dbo].[InstallationHistoryPutByComputerIDUserIDPackageVersionIDReported]
	@ComputerID		int,
	@UserID			int,
	@PackageVersionID	int,
	@Reported		datetime,
	@Action			varchar(10),
	@Received		datetime,
	@FailReasonID		int = NULL,
	@Result			varchar(16) = NULL
AS
	IF NOT EXISTS(
		SELECT	1
		FROM	dbo.InstallationHistory
		WHERE	ComputerID = @ComputerID
		  AND	UserID = @UserID
		  AND	PackageVersionID = @PackageVersionID
		  AND	Reported = @Reported
	)
		EXEC InstallationHistoryAdd @ComputerID,
			@UserID,
			@PackageVersionID,
			@Reported,
			@Action,
			@Received,
			@FailReasonID,
			@Result
	ELSE
		EXEC InstallationHistoryUpdateByComputerIDUserIDPackageVersionIDReported @ComputerID,
			@UserID,
			@PackageVersionID,
			@Reported,
			@Action,
			@Received,
			@FailReasonID,
			@Result
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[InstallationHistoryPutBatchByComputerIDUserIDPackageVersionIDReported]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[InstallationHistoryPutBatchByComputerIDUserIDPackageVersionIDReported]
GO
CREATE PROCEDURE [dbo].[InstallationHistoryPutBatchByComputerIDUserIDPackageVersionIDReported]
AS
	DECLARE @count AS int
	SET @count = 0

	CREATE INDEX [TempInstallationHistoryComputerIDUserIDPackageVersionIDReported]
		ON #InstallationHistory (ComputerID, UserID, PackageVersionID, Reported)

	BEGIN TRANSACTION
	UPDATE [dbo].[InstallationHistory]
		SET	Action = t.Action,
			Received = t.Received,
			FailReasonID = t.FailReasonID,
			Result = t.Result
		FROM	#InstallationHistory AS t
		WHERE	InstallationHistory.ComputerID = t.ComputerID
		  AND	InstallationHistory.UserID = t.UserID
		  AND	InstallationHistory.PackageVersionID = t.PackageVersionID
		  AND	InstallationHistory.Reported = t.Reported
	SET @count = @@ROWCOUNT

	INSERT [dbo].[InstallationHistory] (
		ComputerID,
		UserID,
		PackageVersionID,
		Reported,
		Action,
		Received,
		FailReasonID,
		Result
	)
		SELECT	ComputerID,
			UserID,
			PackageVersionID,
			Reported,
			Action,
			Received,
			FailReasonID,
			Result
		FROM	#InstallationHistory AS t
		WHERE NOT EXISTS(	-- Current record doesn't exist
			SELECT * FROM [dbo].[InstallationHistory]
			WHERE	InstallationHistory.ComputerID = t.ComputerID
			  AND	InstallationHistory.UserID = t.UserID
			  AND	InstallationHistory.PackageVersionID = t.PackageVersionID
			  AND	InstallationHistory.Reported = t.Reported
		)
	SET @count = @count + @@ROWCOUNT
	DROP TABLE #InstallationHistory	-- Drop the temporary table
	COMMIT WORK
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[InstallationHistoryRemoveBatch]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[InstallationHistoryRemoveBatch]
GO

CREATE PROCEDURE [dbo].[InstallationHistoryRemoveBatch]
AS

	CREATE INDEX [TempInstallationHistoryInstallationHistoryRemoveBatch]
		ON #InstallationHistory (ComputerID, UserID, PackageVersionID, Reported)	

	-- Delete records from InstallationHistory identified by fields of [TempInstallationHistoryInstallationHistoryRemoveBatch]
	DELETE [dbo].[InstallationHistory]
	WHERE EXISTS(
			SELECT * FROM #InstallationHistory AS t
			WHERE	InstallationHistory.ComputerID = t.ComputerID
			  AND	InstallationHistory.UserID = t.UserID
			  AND	InstallationHistory.PackageVersionID = t.PackageVersionID
			  AND	InstallationHistory.Reported = t.Reported
		)
	DROP TABLE #InstallationHistory      -- Drop the temporary table
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[InstallationHistoryRemoveByComputerIDUserIDPackageVersionIDReported]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[InstallationHistoryRemoveByComputerIDUserIDPackageVersionIDReported]
GO
CREATE PROCEDURE [dbo].[InstallationHistoryRemoveByComputerIDUserIDPackageVersionIDReported]
	@ComputerID		int,
	@UserID			int,
	@PackageVersionID	int,
	@Reported		datetime
AS
	DELETE	[dbo].[InstallationHistory]
	WHERE	ComputerID = @ComputerID
	  AND	UserID = @UserID
	  AND	PackageVersionID = @PackageVersionID
	  AND	Reported = @Reported
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[InstallationHistoryRemoveAll]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[InstallationHistoryRemoveAll]
GO
CREATE PROCEDURE [dbo].[InstallationHistoryRemoveAll]
	
AS
	DELETE	[dbo].[InstallationHistory]
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[InventoryReportGetByComputerIDUserID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[InventoryReportGetByComputerIDUserID]
GO
CREATE PROCEDURE [dbo].[InventoryReportGetByComputerIDUserID]
	@ComputerID		int,
	@UserID			int
AS
	SELECT	ComputerID,
		UserID,
		SWDate,
		HWDate,
		FilesDate,
		ServicesDate,
		SequenceNumber
	FROM	[dbo].[InventoryReport]
	WHERE	ComputerID = @ComputerID
	  AND	UserID = @UserID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[InventoryReportGetAllByComputerID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[InventoryReportGetAllByComputerID]
GO
CREATE PROCEDURE [dbo].[InventoryReportGetAllByComputerID]
	@ComputerID		int
AS
	SELECT	ComputerID,
		UserID,
		SWDate,
		HWDate,
		FilesDate,
		ServicesDate,
		SequenceNumber
	FROM	[dbo].[InventoryReport]
	WHERE	ComputerID = @ComputerID
	ORDER BY UserID
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[InventoryReportGetAll]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[InventoryReportGetAll]
GO
CREATE PROCEDURE [dbo].[InventoryReportGetAll]
AS
	SELECT	ComputerID,
		UserID,
		SWDate,
		HWDate,
		FilesDate,
		ServicesDate,
		SequenceNumber
	FROM	[dbo].[InventoryReport]
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[InventoryReportAdd]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[InventoryReportAdd]
GO
CREATE PROCEDURE [dbo].[InventoryReportAdd]
	@ComputerID		int,
	@UserID			int,
	@SWDate			datetime = NULL,
	@HWDate			datetime = NULL,
	@FilesDate		datetime = NULL,
	@ServicesDate		datetime = NULL,
	@SequenceNumber		int = NULL
AS
	INSERT INTO  dbo.InventoryReport (
		ComputerID,
		UserID,
		SWDate,
		HWDate,
		FilesDate,
		ServicesDate,
		SequenceNumber
	)
	VALUES (
		@ComputerID,
		@UserID,
		@SWDate,
		@HWDate,
		@FilesDate,
		@ServicesDate,
		@SequenceNumber
	)
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[InventoryReportSchema]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[InventoryReportSchema]
GO
CREATE PROCEDURE [dbo].[InventoryReportSchema]
AS
	SELECT
	'IF OBJECT_ID(''tempdb..#InventoryReport'') IS NULL' + CAST(0x0A AS CHAR(1)) +
	'	CREATE TABLE #InventoryReport (' + CAST(0x0A AS CHAR(1)) +
	'		ComputerID		int NOT NULL,' + CAST(0x0A AS CHAR(1)) +
	'		UserID			int NOT NULL,' + CAST(0x0A AS CHAR(1)) +
	'		SWDate			datetime NULL,' + CAST(0x0A AS CHAR(1)) +
	'		HWDate			datetime NULL,' + CAST(0x0A AS CHAR(1)) +
	'		FilesDate		datetime NULL,' + CAST(0x0A AS CHAR(1)) +
	'		ServicesDate		datetime NULL,' + CAST(0x0A AS CHAR(1)) +
	'		SequenceNumber		int NULL' + CAST(0x0A AS CHAR(1)) +
	'	)' + CAST(0x0A AS CHAR(1)) +
	'ELSE' + CAST(0x0A AS CHAR(1)) +
	'	DELETE FROM #InventoryReport' + CAST(0x0A AS CHAR(1)) +
	'' AS SQL
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[InventoryReportTempAdd]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[InventoryReportTempAdd]
GO
CREATE PROCEDURE dbo.[InventoryReportTempAdd]
	@ComputerID		int,
	@UserID			int,
	@SWDate			datetime = NULL,
	@HWDate			datetime = NULL,
	@FilesDate		datetime = NULL,
	@ServicesDate		datetime = NULL,
	@SequenceNumber		int = NULL
AS
	INSERT INTO #InventoryReport (
		ComputerID,
		UserID,
		SWDate,
		HWDate,
		FilesDate,
		ServicesDate,
		SequenceNumber
	)
	VALUES (
		@ComputerID,
		@UserID,
		@SWDate,
		@HWDate,
		@FilesDate,
		@ServicesDate,
		@SequenceNumber
	)
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[InventoryReportAddBatch]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[InventoryReportAddBatch]
GO
CREATE PROCEDURE dbo.[InventoryReportAddBatch]
AS
	DECLARE @count int
	INSERT dbo.InventoryReport (
		ComputerID,
		UserID,
		SWDate,
		HWDate,
		FilesDate,
		ServicesDate,
		SequenceNumber
	)
		SELECT	ComputerID,
			UserID,
			SWDate,
			HWDate,
			FilesDate,
			ServicesDate,
			SequenceNumber
		FROM #InventoryReport
	SET @count = @@ROWCOUNT
	DROP TABLE #InventoryReport	-- Drop temporary table
	RETURN @count
GO

/*
Add new InventoryReport bound to
	User using UserOUID, UserCN
	with ComputerID, SWDate, HWDate, FilesDate, ServicesDate, SequenceNumber
*/

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[InventoryReportUpdateByComputerIDUserID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[InventoryReportUpdateByComputerIDUserID]
GO
CREATE PROCEDURE [dbo].[InventoryReportUpdateByComputerIDUserID]
	@ComputerID		int,
	@UserID			int,
	@SWDate			datetime = NULL,
	@HWDate			datetime = NULL,
	@FilesDate		datetime = NULL,
	@ServicesDate		datetime = NULL,
	@SequenceNumber		int = NULL
AS
	UPDATE	[dbo].[InventoryReport]
	SET	SWDate = @SWDate,
		HWDate = @HWDate,
		FilesDate = @FilesDate,
		ServicesDate = @ServicesDate,
		SequenceNumber = @SequenceNumber
	WHERE	ComputerID = @ComputerID
	  AND	UserID = @UserID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[InventoryReportUpdateBatchByComputerIDUserID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[InventoryReportUpdateBatchByComputerIDUserID]
GO
CREATE PROCEDURE dbo.[InventoryReportUpdateBatchByComputerIDUserID]
AS
	DECLARE @count int

	CREATE INDEX [TempInventoryReportComputerIDUserID]
		ON #InventoryReport (ComputerID, UserID)

	UPDATE	[dbo].[InventoryReport]
	SET	SWDate = t.SWDate,
		HWDate = t.HWDate,
		FilesDate = t.FilesDate,
		ServicesDate = t.ServicesDate,
		SequenceNumber = t.SequenceNumber
	FROM	#InventoryReport AS t
	WHERE	InventoryReport.ComputerID = t.ComputerID
	  AND	InventoryReport.UserID = t.UserID
	SET @count = @@ROWCOUNT
	DROP TABLE #InventoryReport	-- Drop the temporary table
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[InventoryReportPutByComputerIDUserID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[InventoryReportPutByComputerIDUserID]
GO
CREATE PROCEDURE [dbo].[InventoryReportPutByComputerIDUserID]
	@ComputerID		int,
	@UserID			int,
	@SWDate			datetime = NULL,
	@HWDate			datetime = NULL,
	@FilesDate		datetime = NULL,
	@ServicesDate		datetime = NULL,
	@SequenceNumber		int = NULL
AS
	IF NOT EXISTS(
		SELECT	1
		FROM	dbo.InventoryReport
		WHERE	ComputerID = @ComputerID
		  AND	UserID = @UserID
	)
		EXEC InventoryReportAdd @ComputerID,
			@UserID,
			@SWDate,
			@HWDate,
			@FilesDate,
			@ServicesDate,
			@SequenceNumber
	ELSE
		EXEC InventoryReportUpdateByComputerIDUserID @ComputerID,
			@UserID,
			@SWDate,
			@HWDate,
			@FilesDate,
			@ServicesDate,
			@SequenceNumber
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[InventoryReportPutBatchByComputerIDUserID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[InventoryReportPutBatchByComputerIDUserID]
GO
CREATE PROCEDURE [dbo].[InventoryReportPutBatchByComputerIDUserID]
AS
	DECLARE @count AS int
	SET @count = 0

	CREATE INDEX [TempInventoryReportComputerIDUserID]
		ON #InventoryReport (ComputerID, UserID)

	BEGIN TRANSACTION
	UPDATE [dbo].[InventoryReport]
		SET	SWDate = t.SWDate,
			HWDate = t.HWDate,
			FilesDate = t.FilesDate,
			ServicesDate = t.ServicesDate,
			SequenceNumber = t.SequenceNumber
		FROM	#InventoryReport AS t
		WHERE	InventoryReport.ComputerID = t.ComputerID
		  AND	InventoryReport.UserID = t.UserID
	SET @count = @@ROWCOUNT

	INSERT [dbo].[InventoryReport] (
		ComputerID,
		UserID,
		SWDate,
		HWDate,
		FilesDate,
		ServicesDate,
		SequenceNumber
	)
		SELECT	ComputerID,
			UserID,
			SWDate,
			HWDate,
			FilesDate,
			ServicesDate,
			SequenceNumber
		FROM	#InventoryReport AS t
		WHERE NOT EXISTS(	-- Current record doesn't exist
			SELECT * FROM [dbo].[InventoryReport]
			WHERE	InventoryReport.ComputerID = t.ComputerID
			  AND	InventoryReport.UserID = t.UserID
		)
	SET @count = @count + @@ROWCOUNT
	DROP TABLE #InventoryReport	-- Drop the temporary table
	COMMIT WORK
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[InventoryReportRemoveBatch]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[InventoryReportRemoveBatch]
GO

CREATE PROCEDURE [dbo].[InventoryReportRemoveBatch]
AS

	CREATE INDEX [TempInventoryReportInventoryReportRemoveBatch]
		ON #InventoryReport (ComputerID, UserID)	

	-- Delete records from InventoryReport identified by fields of [TempInventoryReportInventoryReportRemoveBatch]
	DELETE [dbo].[InventoryReport]
	WHERE EXISTS(
			SELECT * FROM #InventoryReport AS t
			WHERE	InventoryReport.ComputerID = t.ComputerID
			  AND	InventoryReport.UserID = t.UserID
		)
	DROP TABLE #InventoryReport      -- Drop the temporary table
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[InventoryReportRemoveByComputerIDUserID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[InventoryReportRemoveByComputerIDUserID]
GO
CREATE PROCEDURE [dbo].[InventoryReportRemoveByComputerIDUserID]
	@ComputerID		int,
	@UserID			int
AS
	DELETE	[dbo].[InventoryReport]
	WHERE	ComputerID = @ComputerID
	  AND	UserID = @UserID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[InventoryReportRemoveAll]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[InventoryReportRemoveAll]
GO
CREATE PROCEDURE [dbo].[InventoryReportRemoveAll]
	
AS
	DELETE	[dbo].[InventoryReport]
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[SoftwareVersionGetByID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[SoftwareVersionGetByID]
GO
CREATE PROCEDURE [dbo].[SoftwareVersionGetByID]
	@SoftwareID		int
AS
	SELECT	SoftwareID,
		SoftwareName,
		Version
	FROM	[dbo].[SoftwareVersion]
	WHERE	SoftwareID = @SoftwareID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[SoftwareVersionGetBySoftwareNameVersion]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[SoftwareVersionGetBySoftwareNameVersion]
GO
CREATE PROCEDURE [dbo].[SoftwareVersionGetBySoftwareNameVersion]
	@SoftwareName		nvarchar(128),
	@Version		nvarchar(32)
AS
	SELECT	SoftwareID,
		SoftwareName,
		Version
	FROM	[dbo].[SoftwareVersion]
	WHERE	SoftwareName = @SoftwareName
	  AND	Version = @Version
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[SoftwareVersionGetAllBySoftwareName]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[SoftwareVersionGetAllBySoftwareName]
GO
CREATE PROCEDURE [dbo].[SoftwareVersionGetAllBySoftwareName]
	@SoftwareName		nvarchar(128)
AS
	SELECT	SoftwareID,
		SoftwareName,
		Version
	FROM	[dbo].[SoftwareVersion]
	WHERE	SoftwareName = @SoftwareName
	ORDER BY Version
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[SoftwareVersionGetAll]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[SoftwareVersionGetAll]
GO
CREATE PROCEDURE [dbo].[SoftwareVersionGetAll]
AS
	SELECT	SoftwareID,
		SoftwareName,
		Version
	FROM	[dbo].[SoftwareVersion]
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[SoftwareVersionAdd]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[SoftwareVersionAdd]
GO
CREATE PROCEDURE [dbo].[SoftwareVersionAdd]
	@SoftwareName		nvarchar(128),
	@Version		nvarchar(32)
AS
	INSERT INTO  dbo.SoftwareVersion (
		SoftwareName,
		Version
	)
	VALUES (
		@SoftwareName,
		@Version
	)
	RETURN SCOPE_IDENTITY()
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[SoftwareVersionBind]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[SoftwareVersionBind]
GO
CREATE PROCEDURE [dbo].[SoftwareVersionBind]
	@SoftwareName		nvarchar(128),
	@Version		nvarchar(32)
AS
	DECLARE	@ID	int

	SELECT	@ID = SoftwareID
	FROM	[dbo].[SoftwareVersion]
	WHERE	SoftwareName = @SoftwareName
	  AND	Version = @Version

	IF @ID IS NULL
		EXEC @ID = SoftwareVersionAdd @SoftwareName,
			@Version

	RETURN @ID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[SoftwareVersionSchema]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[SoftwareVersionSchema]
GO
CREATE PROCEDURE [dbo].[SoftwareVersionSchema]
AS
	SELECT
	'IF OBJECT_ID(''tempdb..#SoftwareVersion'') IS NULL' + CAST(0x0A AS CHAR(1)) +
	'	CREATE TABLE #SoftwareVersion (' + CAST(0x0A AS CHAR(1)) +
	'		SoftwareID		int NULL,' + CAST(0x0A AS CHAR(1)) +
	'		SoftwareName		nvarchar(128) COLLATE database_default NOT NULL,' + CAST(0x0A AS CHAR(1)) +
	'		Version			nvarchar(32) COLLATE database_default NOT NULL' + CAST(0x0A AS CHAR(1)) +
	'	)' + CAST(0x0A AS CHAR(1)) +
	'ELSE' + CAST(0x0A AS CHAR(1)) +
	'	DELETE FROM #SoftwareVersion' + CAST(0x0A AS CHAR(1)) +
	'' AS SQL
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[SoftwareVersionTempAdd]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[SoftwareVersionTempAdd]
GO
CREATE PROCEDURE dbo.[SoftwareVersionTempAdd]
	@SoftwareID		int,
	@SoftwareName		nvarchar(128),
	@Version		nvarchar(32)
AS
	INSERT INTO #SoftwareVersion (
		SoftwareID,
		SoftwareName,
		Version
	)
	VALUES (
		@SoftwareID,
		@SoftwareName,
		@Version
	)
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[SoftwareVersionAddBatch]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[SoftwareVersionAddBatch]
GO
CREATE PROCEDURE dbo.[SoftwareVersionAddBatch]
AS
	DECLARE @count int
	INSERT dbo.SoftwareVersion (
		SoftwareName,
		Version
	)
		SELECT	SoftwareName,
			Version
		FROM #SoftwareVersion
	SET @count = @@ROWCOUNT
	DROP TABLE #SoftwareVersion	-- Drop temporary table
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[SoftwareVersionUpdateByID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[SoftwareVersionUpdateByID]
GO
CREATE PROCEDURE [dbo].[SoftwareVersionUpdateByID]
	@SoftwareID		int,
	@SoftwareName		nvarchar(128),
	@Version		nvarchar(32)
AS
	DECLARE	@ID	int
	SET @ID = 0

	UPDATE	[dbo].[SoftwareVersion]
	SET	@ID = SoftwareID,
		SoftwareName = @SoftwareName,
		Version = @Version
	WHERE	SoftwareID = @SoftwareID
	RETURN @ID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[SoftwareVersionUpdateBatchByID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[SoftwareVersionUpdateBatchByID]
GO
CREATE PROCEDURE dbo.[SoftwareVersionUpdateBatchByID]
AS
	DECLARE @count int

	CREATE INDEX [TempSoftwareVersionID]
		ON #SoftwareVersion (SoftwareID)

	UPDATE	[dbo].[SoftwareVersion]
	SET	SoftwareName = t.SoftwareName,
		Version = t.Version
	FROM	#SoftwareVersion AS t
	WHERE	SoftwareVersion.SoftwareID = t.SoftwareID
	SET @count = @@ROWCOUNT
	DROP TABLE #SoftwareVersion	-- Drop the temporary table
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[SoftwareVersionPutBySoftwareNameVersion]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[SoftwareVersionPutBySoftwareNameVersion]
GO
CREATE PROCEDURE [dbo].[SoftwareVersionPutBySoftwareNameVersion]
	@SoftwareName		nvarchar(128),
	@Version		nvarchar(32)
AS
	DECLARE @ID	int

	SELECT	@ID = SoftwareID
	FROM	SoftwareVersion
	WHERE	SoftwareName = @SoftwareName
	  AND	Version = @Version

	IF @ID IS NULL
		EXEC @ID = SoftwareVersionAdd @SoftwareName,
			@Version

	RETURN @ID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[SoftwareVersionPutBatchBySoftwareNameVersion]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[SoftwareVersionPutBatchBySoftwareNameVersion]
GO
CREATE PROCEDURE [dbo].[SoftwareVersionPutBatchBySoftwareNameVersion]
AS
	DECLARE @count AS int
	SET @count = 0

	CREATE INDEX [TempSoftwareVersionSoftwareNameVersion]
		ON #SoftwareVersion (SoftwareName, Version)

	BEGIN TRANSACTION

	INSERT [dbo].[SoftwareVersion] (
		SoftwareName,
		Version
	)
		SELECT	SoftwareName,
			Version
		FROM	#SoftwareVersion AS t
		WHERE NOT EXISTS(	-- Current record doesn't exist
			SELECT * FROM [dbo].[SoftwareVersion]
			WHERE	SoftwareVersion.SoftwareName = t.SoftwareName
			  AND	SoftwareVersion.Version = t.Version
		)
	SET @count = @count + @@ROWCOUNT
	DROP TABLE #SoftwareVersion	-- Drop the temporary table
	COMMIT WORK
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[SoftwareVersionRemoveBatch]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[SoftwareVersionRemoveBatch]
GO

CREATE PROCEDURE [dbo].[SoftwareVersionRemoveBatch]
AS

	CREATE INDEX [TempSoftwareVersionSoftwareVersionRemoveBatch]
		ON #SoftwareVersion (SoftwareID)	

	-- Delete records from SoftwareVersion identified by fields of [TempSoftwareVersionSoftwareVersionRemoveBatch]
	DELETE [dbo].[SoftwareVersion]
	WHERE EXISTS(
			SELECT * FROM #SoftwareVersion AS t
			WHERE	SoftwareVersion.SoftwareID = t.SoftwareID
		)
	DROP TABLE #SoftwareVersion      -- Drop the temporary table
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[SoftwareVersionRemoveByID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[SoftwareVersionRemoveByID]
GO
CREATE PROCEDURE [dbo].[SoftwareVersionRemoveByID]
	@SoftwareID		int
AS
	-- SoftwareVersion deletes cascade to:
	--	SoftwareOccurrence by FK_SoftwareOccurrence_Software
	--		SoftwareValue by FK_SoftwareValue_SoftwareOccurrence
	--	SoftwareFile by FK_SoftwareFile_Software
	--		SoftwareFileProperty by FK_SoftwareFileProperty_SoftwareFile
	--	ProductContainsSoftware by FK_ProductContains_SoftwareVersionID
	--	SoftwareUsagePerWeek by FK_SoftwareUsagePerWeek_Software
	DELETE	[dbo].[SoftwareVersion]
	WHERE	SoftwareID = @SoftwareID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[SoftwareVersionRemoveBySoftwareNameVersion]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[SoftwareVersionRemoveBySoftwareNameVersion]
GO
CREATE PROCEDURE [dbo].[SoftwareVersionRemoveBySoftwareNameVersion]
	@SoftwareName		nvarchar(128),
	@Version		nvarchar(32)
AS
	-- SoftwareVersion deletes cascade to:
	--	SoftwareOccurrence by FK_SoftwareOccurrence_Software
	--		SoftwareValue by FK_SoftwareValue_SoftwareOccurrence
	--	SoftwareFile by FK_SoftwareFile_Software
	--		SoftwareFileProperty by FK_SoftwareFileProperty_SoftwareFile
	--	ProductContainsSoftware by FK_ProductContains_SoftwareVersionID
	--	SoftwareUsagePerWeek by FK_SoftwareUsagePerWeek_Software
	DELETE	[dbo].[SoftwareVersion]
	WHERE	SoftwareName = @SoftwareName
	  AND	Version = @Version
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[SoftwareVersionRemoveAll]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[SoftwareVersionRemoveAll]
GO
CREATE PROCEDURE [dbo].[SoftwareVersionRemoveAll]
	
AS
	DELETE	[dbo].[SoftwareVersion]
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[SoftwareDetailsGetByID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[SoftwareDetailsGetByID]
GO
CREATE PROCEDURE [dbo].[SoftwareDetailsGetByID]
	@SoftwareDetailsID	int
AS
	SELECT	SoftwareDetailsID,
		RawSoftwareName,
		RawVersion,
		Publisher,
		ProductID
	FROM	[dbo].[SoftwareDetails]
	WHERE	SoftwareDetailsID = @SoftwareDetailsID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[SoftwareDetailsGetByRawSoftwareNameRawVersionPublisherProductID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[SoftwareDetailsGetByRawSoftwareNameRawVersionPublisherProductID]
GO
CREATE PROCEDURE [dbo].[SoftwareDetailsGetByRawSoftwareNameRawVersionPublisherProductID]
	@RawSoftwareName	nvarchar(128),
	@RawVersion		nvarchar(32),
	@Publisher		nvarchar(256),
	@ProductID		nvarchar(256)
AS
	SELECT	SoftwareDetailsID,
		RawSoftwareName,
		RawVersion,
		Publisher,
		ProductID
	FROM	[dbo].[SoftwareDetails]
	WHERE	RawSoftwareName = @RawSoftwareName
	  AND	RawVersion = @RawVersion
	  AND	Publisher = @Publisher
	  AND	ProductID = @ProductID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[SoftwareDetailsGetAllByRawSoftwareName]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[SoftwareDetailsGetAllByRawSoftwareName]
GO
CREATE PROCEDURE [dbo].[SoftwareDetailsGetAllByRawSoftwareName]
	@RawSoftwareName	nvarchar(128)
AS
	SELECT	SoftwareDetailsID,
		RawSoftwareName,
		RawVersion,
		Publisher,
		ProductID
	FROM	[dbo].[SoftwareDetails]
	WHERE	RawSoftwareName = @RawSoftwareName
	ORDER BY RawVersion, Publisher, ProductID
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[SoftwareDetailsGetAll]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[SoftwareDetailsGetAll]
GO
CREATE PROCEDURE [dbo].[SoftwareDetailsGetAll]
AS
	SELECT	SoftwareDetailsID,
		RawSoftwareName,
		RawVersion,
		Publisher,
		ProductID
	FROM	[dbo].[SoftwareDetails]
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[SoftwareDetailsAdd]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[SoftwareDetailsAdd]
GO
CREATE PROCEDURE [dbo].[SoftwareDetailsAdd]
	@RawSoftwareName	nvarchar(128),
	@RawVersion		nvarchar(32),
	@Publisher		nvarchar(256),
	@ProductID		nvarchar(256)
AS
	INSERT INTO  dbo.SoftwareDetails (
		RawSoftwareName,
		RawVersion,
		Publisher,
		ProductID
	)
	VALUES (
		@RawSoftwareName,
		@RawVersion,
		@Publisher,
		@ProductID
	)
	RETURN SCOPE_IDENTITY()
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[SoftwareDetailsBind]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[SoftwareDetailsBind]
GO
CREATE PROCEDURE [dbo].[SoftwareDetailsBind]
	@RawSoftwareName	nvarchar(128),
	@RawVersion		nvarchar(32),
	@Publisher		nvarchar(256),
	@ProductID		nvarchar(256)
AS
	DECLARE	@ID	int

	SELECT	@ID = SoftwareDetailsID
	FROM	[dbo].[SoftwareDetails]
	WHERE	RawSoftwareName = @RawSoftwareName
	  AND	RawVersion = @RawVersion
	  AND	Publisher = @Publisher
	  AND	ProductID = @ProductID

	IF @ID IS NULL
		EXEC @ID = SoftwareDetailsAdd @RawSoftwareName,
			@RawVersion,
			@Publisher,
			@ProductID

	RETURN @ID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[SoftwareDetailsSchema]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[SoftwareDetailsSchema]
GO
CREATE PROCEDURE [dbo].[SoftwareDetailsSchema]
AS
	SELECT
	'IF OBJECT_ID(''tempdb..#SoftwareDetails'') IS NULL' + CAST(0x0A AS CHAR(1)) +
	'	CREATE TABLE #SoftwareDetails (' + CAST(0x0A AS CHAR(1)) +
	'		SoftwareDetailsID	int NULL,' + CAST(0x0A AS CHAR(1)) +
	'		RawSoftwareName		nvarchar(128) COLLATE database_default NOT NULL,' + CAST(0x0A AS CHAR(1)) +
	'		RawVersion		nvarchar(32) COLLATE database_default NOT NULL,' + CAST(0x0A AS CHAR(1)) +
	'		Publisher		nvarchar(256) COLLATE database_default NOT NULL,' + CAST(0x0A AS CHAR(1)) +
	'		ProductID		nvarchar(256) COLLATE database_default NOT NULL' + CAST(0x0A AS CHAR(1)) +
	'	)' + CAST(0x0A AS CHAR(1)) +
	'ELSE' + CAST(0x0A AS CHAR(1)) +
	'	DELETE FROM #SoftwareDetails' + CAST(0x0A AS CHAR(1)) +
	'' AS SQL
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[SoftwareDetailsTempAdd]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[SoftwareDetailsTempAdd]
GO
CREATE PROCEDURE dbo.[SoftwareDetailsTempAdd]
	@SoftwareDetailsID	int,
	@RawSoftwareName	nvarchar(128),
	@RawVersion		nvarchar(32),
	@Publisher		nvarchar(256),
	@ProductID		nvarchar(256)
AS
	INSERT INTO #SoftwareDetails (
		SoftwareDetailsID,
		RawSoftwareName,
		RawVersion,
		Publisher,
		ProductID
	)
	VALUES (
		@SoftwareDetailsID,
		@RawSoftwareName,
		@RawVersion,
		@Publisher,
		@ProductID
	)
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[SoftwareDetailsAddBatch]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[SoftwareDetailsAddBatch]
GO
CREATE PROCEDURE dbo.[SoftwareDetailsAddBatch]
AS
	DECLARE @count int
	INSERT dbo.SoftwareDetails (
		RawSoftwareName,
		RawVersion,
		Publisher,
		ProductID
	)
		SELECT	RawSoftwareName,
			RawVersion,
			Publisher,
			ProductID
		FROM #SoftwareDetails
	SET @count = @@ROWCOUNT
	DROP TABLE #SoftwareDetails	-- Drop temporary table
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[SoftwareDetailsUpdateByID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[SoftwareDetailsUpdateByID]
GO
CREATE PROCEDURE [dbo].[SoftwareDetailsUpdateByID]
	@SoftwareDetailsID	int,
	@RawSoftwareName	nvarchar(128),
	@RawVersion		nvarchar(32),
	@Publisher		nvarchar(256),
	@ProductID		nvarchar(256)
AS
	DECLARE	@ID	int
	SET @ID = 0

	UPDATE	[dbo].[SoftwareDetails]
	SET	@ID = SoftwareDetailsID,
		RawSoftwareName = @RawSoftwareName,
		RawVersion = @RawVersion,
		Publisher = @Publisher,
		ProductID = @ProductID
	WHERE	SoftwareDetailsID = @SoftwareDetailsID
	RETURN @ID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[SoftwareDetailsUpdateBatchByID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[SoftwareDetailsUpdateBatchByID]
GO
CREATE PROCEDURE dbo.[SoftwareDetailsUpdateBatchByID]
AS
	DECLARE @count int

	CREATE INDEX [TempSoftwareDetailsID]
		ON #SoftwareDetails (SoftwareDetailsID)

	UPDATE	[dbo].[SoftwareDetails]
	SET	RawSoftwareName = t.RawSoftwareName,
		RawVersion = t.RawVersion,
		Publisher = t.Publisher,
		ProductID = t.ProductID
	FROM	#SoftwareDetails AS t
	WHERE	SoftwareDetails.SoftwareDetailsID = t.SoftwareDetailsID
	SET @count = @@ROWCOUNT
	DROP TABLE #SoftwareDetails	-- Drop the temporary table
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[SoftwareDetailsPutByRawSoftwareNameRawVersionPublisherProductID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[SoftwareDetailsPutByRawSoftwareNameRawVersionPublisherProductID]
GO
CREATE PROCEDURE [dbo].[SoftwareDetailsPutByRawSoftwareNameRawVersionPublisherProductID]
	@RawSoftwareName	nvarchar(128),
	@RawVersion		nvarchar(32),
	@Publisher		nvarchar(256),
	@ProductID		nvarchar(256)
AS
	DECLARE @ID	int

	SELECT	@ID = SoftwareDetailsID
	FROM	SoftwareDetails
	WHERE	RawSoftwareName = @RawSoftwareName
	  AND	RawVersion = @RawVersion
	  AND	Publisher = @Publisher
	  AND	ProductID = @ProductID

	IF @ID IS NULL
		EXEC @ID = SoftwareDetailsAdd @RawSoftwareName,
			@RawVersion,
			@Publisher,
			@ProductID

	RETURN @ID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[SoftwareDetailsPutBatchByRawSoftwareNameRawVersionPublisherProductID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[SoftwareDetailsPutBatchByRawSoftwareNameRawVersionPublisherProductID]
GO
CREATE PROCEDURE [dbo].[SoftwareDetailsPutBatchByRawSoftwareNameRawVersionPublisherProductID]
AS
	DECLARE @count AS int
	SET @count = 0

	CREATE INDEX [TempSoftwareDetailsRawSoftwareNameRawVersionPublisherProductID]
		ON #SoftwareDetails (RawSoftwareName, RawVersion, Publisher, ProductID)

	BEGIN TRANSACTION

	INSERT [dbo].[SoftwareDetails] (
		RawSoftwareName,
		RawVersion,
		Publisher,
		ProductID
	)
		SELECT	RawSoftwareName,
			RawVersion,
			Publisher,
			ProductID
		FROM	#SoftwareDetails AS t
		WHERE NOT EXISTS(	-- Current record doesn't exist
			SELECT * FROM [dbo].[SoftwareDetails]
			WHERE	SoftwareDetails.RawSoftwareName = t.RawSoftwareName
			  AND	SoftwareDetails.RawVersion = t.RawVersion
			  AND	SoftwareDetails.Publisher = t.Publisher
			  AND	SoftwareDetails.ProductID = t.ProductID
		)
	SET @count = @count + @@ROWCOUNT
	DROP TABLE #SoftwareDetails	-- Drop the temporary table
	COMMIT WORK
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[SoftwareDetailsRemoveBatch]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[SoftwareDetailsRemoveBatch]
GO

CREATE PROCEDURE [dbo].[SoftwareDetailsRemoveBatch]
AS

	CREATE INDEX [TempSoftwareDetailsSoftwareDetailsRemoveBatch]
		ON #SoftwareDetails (SoftwareDetailsID)	

	-- Delete records from SoftwareDetails identified by fields of [TempSoftwareDetailsSoftwareDetailsRemoveBatch]
	DELETE [dbo].[SoftwareDetails]
	WHERE EXISTS(
			SELECT * FROM #SoftwareDetails AS t
			WHERE	SoftwareDetails.SoftwareDetailsID = t.SoftwareDetailsID
		)
	DROP TABLE #SoftwareDetails      -- Drop the temporary table
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[SoftwareDetailsRemoveByID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[SoftwareDetailsRemoveByID]
GO
CREATE PROCEDURE [dbo].[SoftwareDetailsRemoveByID]
	@SoftwareDetailsID	int
AS
	-- SoftwareDetails deletes cascade to:
	--	SoftwareOccurrence by FK_SoftwareOccurrence_SoftwareDetails
	--		SoftwareValue by FK_SoftwareValue_SoftwareOccurrence
	DELETE	[dbo].[SoftwareDetails]
	WHERE	SoftwareDetailsID = @SoftwareDetailsID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[SoftwareDetailsRemoveByRawSoftwareNameRawVersionPublisherProductID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[SoftwareDetailsRemoveByRawSoftwareNameRawVersionPublisherProductID]
GO
CREATE PROCEDURE [dbo].[SoftwareDetailsRemoveByRawSoftwareNameRawVersionPublisherProductID]
	@RawSoftwareName	nvarchar(128),
	@RawVersion		nvarchar(32),
	@Publisher		nvarchar(256),
	@ProductID		nvarchar(256)
AS
	-- SoftwareDetails deletes cascade to:
	--	SoftwareOccurrence by FK_SoftwareOccurrence_SoftwareDetails
	--		SoftwareValue by FK_SoftwareValue_SoftwareOccurrence
	DELETE	[dbo].[SoftwareDetails]
	WHERE	RawSoftwareName = @RawSoftwareName
	  AND	RawVersion = @RawVersion
	  AND	Publisher = @Publisher
	  AND	ProductID = @ProductID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[SoftwareDetailsRemoveAll]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[SoftwareDetailsRemoveAll]
GO
CREATE PROCEDURE [dbo].[SoftwareDetailsRemoveAll]
	
AS
	DELETE	[dbo].[SoftwareDetails]
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[SoftwareOccurrenceGetBySoftwareIDSoftwareDetailsIDComputerIDUserID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[SoftwareOccurrenceGetBySoftwareIDSoftwareDetailsIDComputerIDUserID]
GO
CREATE PROCEDURE [dbo].[SoftwareOccurrenceGetBySoftwareIDSoftwareDetailsIDComputerIDUserID]
	@SoftwareID		int,
	@SoftwareDetailsID	int,
	@ComputerID		int,
	@UserID			int
AS
	SELECT	SoftwareOccurrenceID,
		ComputerID,
		UserID,
		SoftwareID,
		SoftwareDetailsID,
		Evidence,
		PackagePathID,
		PolicyGUID,
		InstallationDate
	FROM	[dbo].[SoftwareOccurrence]
	WHERE	SoftwareID = @SoftwareID
	  AND	SoftwareDetailsID = @SoftwareDetailsID
	  AND	ComputerID = @ComputerID
	  AND	UserID = @UserID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[SoftwareOccurrenceGetByID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[SoftwareOccurrenceGetByID]
GO
CREATE PROCEDURE [dbo].[SoftwareOccurrenceGetByID]
	@SoftwareOccurrenceID	int
AS
	SELECT	SoftwareOccurrenceID,
		ComputerID,
		UserID,
		SoftwareID,
		SoftwareDetailsID,
		Evidence,
		PackagePathID,
		PolicyGUID,
		InstallationDate
	FROM	[dbo].[SoftwareOccurrence]
	WHERE	SoftwareOccurrenceID = @SoftwareOccurrenceID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[SoftwareOccurrenceGetByComputerIDUserIDSoftwareIDSoftwareDetailsID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[SoftwareOccurrenceGetByComputerIDUserIDSoftwareIDSoftwareDetailsID]
GO
CREATE PROCEDURE [dbo].[SoftwareOccurrenceGetByComputerIDUserIDSoftwareIDSoftwareDetailsID]
	@ComputerID		int,
	@UserID			int,
	@SoftwareID		int,
	@SoftwareDetailsID	int
AS
	SELECT	SoftwareOccurrenceID,
		ComputerID,
		UserID,
		SoftwareID,
		SoftwareDetailsID,
		Evidence,
		PackagePathID,
		PolicyGUID,
		InstallationDate
	FROM	[dbo].[SoftwareOccurrence]
	WHERE	ComputerID = @ComputerID
	  AND	UserID = @UserID
	  AND	SoftwareID = @SoftwareID
	  AND	SoftwareDetailsID = @SoftwareDetailsID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[SoftwareOccurrenceGetAllByComputerIDUserID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[SoftwareOccurrenceGetAllByComputerIDUserID]
GO
CREATE PROCEDURE [dbo].[SoftwareOccurrenceGetAllByComputerIDUserID]
	@ComputerID		int,
	@UserID			int
AS
	SELECT	SoftwareOccurrenceID,
		ComputerID,
		UserID,
		SoftwareID,
		SoftwareDetailsID,
		Evidence,
		PackagePathID,
		PolicyGUID,
		InstallationDate
	FROM	[dbo].[SoftwareOccurrence]
	WHERE	ComputerID = @ComputerID
	  AND	UserID = @UserID
	ORDER BY SoftwareID, SoftwareDetailsID
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[SoftwareOccurrenceGetAll]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[SoftwareOccurrenceGetAll]
GO
CREATE PROCEDURE [dbo].[SoftwareOccurrenceGetAll]
AS
	SELECT	SoftwareOccurrenceID,
		ComputerID,
		UserID,
		SoftwareID,
		SoftwareDetailsID,
		Evidence,
		PackagePathID,
		PolicyGUID,
		InstallationDate
	FROM	[dbo].[SoftwareOccurrence]
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[SoftwareOccurrenceAdd]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[SoftwareOccurrenceAdd]
GO
CREATE PROCEDURE [dbo].[SoftwareOccurrenceAdd]
	@ComputerID		int,
	@UserID			int,
	@SoftwareID		int,
	@SoftwareDetailsID	int,
	@Evidence		varchar(32) = NULL,
	@PackagePathID		int = NULL,
	@PolicyGUID		binary(16) = NULL,
	@InstallationDate	datetime = NULL
AS
	INSERT INTO  dbo.SoftwareOccurrence (
		ComputerID,
		UserID,
		SoftwareID,
		SoftwareDetailsID,
		Evidence,
		PackagePathID,
		PolicyGUID,
		InstallationDate
	)
	VALUES (
		@ComputerID,
		@UserID,
		@SoftwareID,
		@SoftwareDetailsID,
		@Evidence,
		@PackagePathID,
		@PolicyGUID,
		@InstallationDate
	)
	RETURN SCOPE_IDENTITY()
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[SoftwareOccurrenceBind]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[SoftwareOccurrenceBind]
GO
CREATE PROCEDURE [dbo].[SoftwareOccurrenceBind]
	@ComputerID		int,
	@UserID			int,
	@SoftwareID		int,
	@SoftwareDetailsID	int,
	@Evidence		varchar(32) = NULL,
	@PackagePathID		int = NULL,
	@PolicyGUID		binary(16) = NULL,
	@InstallationDate	datetime = NULL
AS
	DECLARE	@ID	int

	SELECT	@ID = SoftwareOccurrenceID
	FROM	[dbo].[SoftwareOccurrence]
	WHERE	ComputerID = @ComputerID
	  AND	UserID = @UserID
	  AND	SoftwareID = @SoftwareID
	  AND	SoftwareDetailsID = @SoftwareDetailsID

	IF @ID IS NULL
		EXEC @ID = SoftwareOccurrenceAdd @ComputerID,
			@UserID,
			@SoftwareID,
			@SoftwareDetailsID,
			@Evidence,
			@PackagePathID,
			@PolicyGUID,
			@InstallationDate

	RETURN @ID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[SoftwareOccurrenceSchema]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[SoftwareOccurrenceSchema]
GO
CREATE PROCEDURE [dbo].[SoftwareOccurrenceSchema]
AS
	SELECT
	'IF OBJECT_ID(''tempdb..#SoftwareOccurrence'') IS NULL' + CAST(0x0A AS CHAR(1)) +
	'	CREATE TABLE #SoftwareOccurrence (' + CAST(0x0A AS CHAR(1)) +
	'		SoftwareOccurrenceID	int NULL,' + CAST(0x0A AS CHAR(1)) +
	'		ComputerID		int NOT NULL,' + CAST(0x0A AS CHAR(1)) +
	'		UserID			int NOT NULL,' + CAST(0x0A AS CHAR(1)) +
	'		SoftwareID		int NOT NULL,' + CAST(0x0A AS CHAR(1)) +
	'		SoftwareDetailsID	int NOT NULL,' + CAST(0x0A AS CHAR(1)) +
	'		Evidence		varchar(32) COLLATE database_default NULL,' + CAST(0x0A AS CHAR(1)) +
	'		PackagePathID		int NULL,' + CAST(0x0A AS CHAR(1)) +
	'		PolicyGUID		binary(16) NULL,' + CAST(0x0A AS CHAR(1)) +
	'		InstallationDate	datetime NULL' + CAST(0x0A AS CHAR(1)) +
	'	)' + CAST(0x0A AS CHAR(1)) +
	'ELSE' + CAST(0x0A AS CHAR(1)) +
	'	DELETE FROM #SoftwareOccurrence' + CAST(0x0A AS CHAR(1)) +
	'' AS SQL
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[SoftwareOccurrenceTempAdd]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[SoftwareOccurrenceTempAdd]
GO
CREATE PROCEDURE dbo.[SoftwareOccurrenceTempAdd]
	@SoftwareOccurrenceID	int,
	@ComputerID		int,
	@UserID			int,
	@SoftwareID		int,
	@SoftwareDetailsID	int,
	@Evidence		varchar(32) = NULL,
	@PackagePathID		int = NULL,
	@PolicyGUID		binary(16) = NULL,
	@InstallationDate	datetime = NULL
AS
	INSERT INTO #SoftwareOccurrence (
		SoftwareOccurrenceID,
		ComputerID,
		UserID,
		SoftwareID,
		SoftwareDetailsID,
		Evidence,
		PackagePathID,
		PolicyGUID,
		InstallationDate
	)
	VALUES (
		@SoftwareOccurrenceID,
		@ComputerID,
		@UserID,
		@SoftwareID,
		@SoftwareDetailsID,
		@Evidence,
		@PackagePathID,
		@PolicyGUID,
		@InstallationDate
	)
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[SoftwareOccurrenceAddBatch]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[SoftwareOccurrenceAddBatch]
GO
CREATE PROCEDURE dbo.[SoftwareOccurrenceAddBatch]
AS
	DECLARE @count int
	INSERT dbo.SoftwareOccurrence (
		ComputerID,
		UserID,
		SoftwareID,
		SoftwareDetailsID,
		Evidence,
		PackagePathID,
		PolicyGUID,
		InstallationDate
	)
		SELECT	ComputerID,
			UserID,
			SoftwareID,
			SoftwareDetailsID,
			Evidence,
			PackagePathID,
			PolicyGUID,
			InstallationDate
		FROM #SoftwareOccurrence
	SET @count = @@ROWCOUNT
	DROP TABLE #SoftwareOccurrence	-- Drop temporary table
	RETURN @count
GO

/*
Add new SoftwareOccurrence bound to
	SoftwareVersion using SoftwareName, Version
	SoftwareDetails using RawSoftwareName, RawVersion, Publisher, ProductID
	User using UserOUID, UserCN
	with ComputerID, Evidence, PackagePathID, PolicyGUID, InstallationDate
*/

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[SoftwareOccurrenceUpdateByID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[SoftwareOccurrenceUpdateByID]
GO
CREATE PROCEDURE [dbo].[SoftwareOccurrenceUpdateByID]
	@SoftwareOccurrenceID	int,
	@ComputerID		int,
	@UserID			int,
	@SoftwareID		int,
	@SoftwareDetailsID	int,
	@Evidence		varchar(32) = NULL,
	@PackagePathID		int = NULL,
	@PolicyGUID		binary(16) = NULL,
	@InstallationDate	datetime = NULL
AS
	DECLARE	@ID	int
	SET @ID = 0

	UPDATE	[dbo].[SoftwareOccurrence]
	SET	@ID = SoftwareOccurrenceID,
		ComputerID = @ComputerID,
		UserID = @UserID,
		SoftwareID = @SoftwareID,
		SoftwareDetailsID = @SoftwareDetailsID,
		Evidence = @Evidence,
		PackagePathID = @PackagePathID,
		PolicyGUID = @PolicyGUID,
		InstallationDate = @InstallationDate
	WHERE	SoftwareOccurrenceID = @SoftwareOccurrenceID
	RETURN @ID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[SoftwareOccurrenceUpdateBatchByID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[SoftwareOccurrenceUpdateBatchByID]
GO
CREATE PROCEDURE dbo.[SoftwareOccurrenceUpdateBatchByID]
AS
	DECLARE @count int

	CREATE INDEX [TempSoftwareOccurrenceID]
		ON #SoftwareOccurrence (SoftwareOccurrenceID)

	UPDATE	[dbo].[SoftwareOccurrence]
	SET	ComputerID = t.ComputerID,
		UserID = t.UserID,
		SoftwareID = t.SoftwareID,
		SoftwareDetailsID = t.SoftwareDetailsID,
		Evidence = t.Evidence,
		PackagePathID = t.PackagePathID,
		PolicyGUID = t.PolicyGUID,
		InstallationDate = t.InstallationDate
	FROM	#SoftwareOccurrence AS t
	WHERE	SoftwareOccurrence.SoftwareOccurrenceID = t.SoftwareOccurrenceID
	SET @count = @@ROWCOUNT
	DROP TABLE #SoftwareOccurrence	-- Drop the temporary table
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[SoftwareOccurrenceUpdateByComputerIDUserIDSoftwareIDSoftwareDetailsID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[SoftwareOccurrenceUpdateByComputerIDUserIDSoftwareIDSoftwareDetailsID]
GO
CREATE PROCEDURE [dbo].[SoftwareOccurrenceUpdateByComputerIDUserIDSoftwareIDSoftwareDetailsID]
	@ComputerID		int,
	@UserID			int,
	@SoftwareID		int,
	@SoftwareDetailsID	int,
	@Evidence		varchar(32) = NULL,
	@PackagePathID		int = NULL,
	@PolicyGUID		binary(16) = NULL,
	@InstallationDate	datetime = NULL
AS
	DECLARE	@ID	int
	SET @ID = 0

	UPDATE	[dbo].[SoftwareOccurrence]
	SET	@ID = SoftwareOccurrenceID,
		Evidence = @Evidence,
		PackagePathID = @PackagePathID,
		PolicyGUID = @PolicyGUID,
		InstallationDate = @InstallationDate
	WHERE	ComputerID = @ComputerID
	  AND	UserID = @UserID
	  AND	SoftwareID = @SoftwareID
	  AND	SoftwareDetailsID = @SoftwareDetailsID
	RETURN @ID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[SoftwareOccurrenceUpdateBatchByComputerIDUserIDSoftwareIDSoftwareDetailsID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[SoftwareOccurrenceUpdateBatchByComputerIDUserIDSoftwareIDSoftwareDetailsID]
GO
CREATE PROCEDURE dbo.[SoftwareOccurrenceUpdateBatchByComputerIDUserIDSoftwareIDSoftwareDetailsID]
AS
	DECLARE @count int

	CREATE INDEX [TempSoftwareOccurrenceComputerIDUserIDSoftwareIDSoftwareDetailsID]
		ON #SoftwareOccurrence (ComputerID, UserID, SoftwareID, SoftwareDetailsID)

	UPDATE	[dbo].[SoftwareOccurrence]
	SET	Evidence = t.Evidence,
		PackagePathID = t.PackagePathID,
		PolicyGUID = t.PolicyGUID,
		InstallationDate = t.InstallationDate
	FROM	#SoftwareOccurrence AS t
	WHERE	SoftwareOccurrence.ComputerID = t.ComputerID
	  AND	SoftwareOccurrence.UserID = t.UserID
	  AND	SoftwareOccurrence.SoftwareID = t.SoftwareID
	  AND	SoftwareOccurrence.SoftwareDetailsID = t.SoftwareDetailsID
	SET @count = @@ROWCOUNT
	DROP TABLE #SoftwareOccurrence	-- Drop the temporary table
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[SoftwareOccurrencePutByComputerIDUserIDSoftwareIDSoftwareDetailsID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[SoftwareOccurrencePutByComputerIDUserIDSoftwareIDSoftwareDetailsID]
GO
CREATE PROCEDURE [dbo].[SoftwareOccurrencePutByComputerIDUserIDSoftwareIDSoftwareDetailsID]
	@ComputerID		int,
	@UserID			int,
	@SoftwareID		int,
	@SoftwareDetailsID	int,
	@Evidence		varchar(32) = NULL,
	@PackagePathID		int = NULL,
	@PolicyGUID		binary(16) = NULL,
	@InstallationDate	datetime = NULL
AS
	DECLARE @ID	int

	SELECT	@ID = SoftwareOccurrenceID
	FROM	SoftwareOccurrence
	WHERE	ComputerID = @ComputerID
	  AND	UserID = @UserID
	  AND	SoftwareID = @SoftwareID
	  AND	SoftwareDetailsID = @SoftwareDetailsID

	IF @ID IS NULL
		EXEC @ID = SoftwareOccurrenceAdd @ComputerID,
			@UserID,
			@SoftwareID,
			@SoftwareDetailsID,
			@Evidence,
			@PackagePathID,
			@PolicyGUID,
			@InstallationDate
	ELSE
		EXEC SoftwareOccurrenceUpdateByComputerIDUserIDSoftwareIDSoftwareDetailsID @ComputerID,
			@UserID,
			@SoftwareID,
			@SoftwareDetailsID,
			@Evidence,
			@PackagePathID,
			@PolicyGUID,
			@InstallationDate

	RETURN @ID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[SoftwareOccurrencePutBatchByComputerIDUserIDSoftwareIDSoftwareDetailsID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[SoftwareOccurrencePutBatchByComputerIDUserIDSoftwareIDSoftwareDetailsID]
GO
CREATE PROCEDURE [dbo].[SoftwareOccurrencePutBatchByComputerIDUserIDSoftwareIDSoftwareDetailsID]
AS
	DECLARE @count AS int
	SET @count = 0

	CREATE INDEX [TempSoftwareOccurrenceComputerIDUserIDSoftwareIDSoftwareDetailsID]
		ON #SoftwareOccurrence (ComputerID, UserID, SoftwareID, SoftwareDetailsID)

	BEGIN TRANSACTION
	UPDATE [dbo].[SoftwareOccurrence]
		SET	Evidence = t.Evidence,
			PackagePathID = t.PackagePathID,
			PolicyGUID = t.PolicyGUID,
			InstallationDate = t.InstallationDate
		FROM	#SoftwareOccurrence AS t
		WHERE	SoftwareOccurrence.ComputerID = t.ComputerID
		  AND	SoftwareOccurrence.UserID = t.UserID
		  AND	SoftwareOccurrence.SoftwareID = t.SoftwareID
		  AND	SoftwareOccurrence.SoftwareDetailsID = t.SoftwareDetailsID
	SET @count = @@ROWCOUNT

	INSERT [dbo].[SoftwareOccurrence] (
		ComputerID,
		UserID,
		SoftwareID,
		SoftwareDetailsID,
		Evidence,
		PackagePathID,
		PolicyGUID,
		InstallationDate
	)
		SELECT	ComputerID,
			UserID,
			SoftwareID,
			SoftwareDetailsID,
			Evidence,
			PackagePathID,
			PolicyGUID,
			InstallationDate
		FROM	#SoftwareOccurrence AS t
		WHERE NOT EXISTS(	-- Current record doesn't exist
			SELECT * FROM [dbo].[SoftwareOccurrence]
			WHERE	SoftwareOccurrence.ComputerID = t.ComputerID
			  AND	SoftwareOccurrence.UserID = t.UserID
			  AND	SoftwareOccurrence.SoftwareID = t.SoftwareID
			  AND	SoftwareOccurrence.SoftwareDetailsID = t.SoftwareDetailsID
		)
	SET @count = @count + @@ROWCOUNT
	DROP TABLE #SoftwareOccurrence	-- Drop the temporary table
	COMMIT WORK
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[SoftwareOccurrenceRemoveBatch]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[SoftwareOccurrenceRemoveBatch]
GO

CREATE PROCEDURE [dbo].[SoftwareOccurrenceRemoveBatch]
AS

	CREATE INDEX [TempSoftwareOccurrenceSoftwareOccurrenceRemoveBatch]
		ON #SoftwareOccurrence (SoftwareOccurrenceID)	

	-- Delete records from SoftwareOccurrence identified by fields of [TempSoftwareOccurrenceSoftwareOccurrenceRemoveBatch]
	DELETE [dbo].[SoftwareOccurrence]
	WHERE EXISTS(
			SELECT * FROM #SoftwareOccurrence AS t
			WHERE	SoftwareOccurrence.SoftwareOccurrenceID = t.SoftwareOccurrenceID
		)
	DROP TABLE #SoftwareOccurrence      -- Drop the temporary table
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[SoftwareOccurrenceRemoveAllBySoftwareIDSoftwareDetailsID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[SoftwareOccurrenceRemoveAllBySoftwareIDSoftwareDetailsID]
GO
CREATE PROCEDURE [dbo].[SoftwareOccurrenceRemoveAllBySoftwareIDSoftwareDetailsID]
	@SoftwareID		int,
	@SoftwareDetailsID	int
AS
	DELETE	[dbo].[SoftwareOccurrence]
	WHERE	SoftwareID = @SoftwareID
	  AND	SoftwareDetailsID = @SoftwareDetailsID
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[SoftwareOccurrenceRemoveAllBySoftwareID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[SoftwareOccurrenceRemoveAllBySoftwareID]
GO
CREATE PROCEDURE [dbo].[SoftwareOccurrenceRemoveAllBySoftwareID]
	@SoftwareID		int
AS
	DELETE	[dbo].[SoftwareOccurrence]
	WHERE	SoftwareID = @SoftwareID
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[SoftwareOccurrenceRemoveByComputerIDUserIDSoftwareIDSoftwareDetailsID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[SoftwareOccurrenceRemoveByComputerIDUserIDSoftwareIDSoftwareDetailsID]
GO
CREATE PROCEDURE [dbo].[SoftwareOccurrenceRemoveByComputerIDUserIDSoftwareIDSoftwareDetailsID]
	@ComputerID		int,
	@UserID			int,
	@SoftwareID		int,
	@SoftwareDetailsID	int
AS
	-- SoftwareOccurrence deletes cascade to:
	--	SoftwareValue by FK_SoftwareValue_SoftwareOccurrence
	DELETE	[dbo].[SoftwareOccurrence]
	WHERE	ComputerID = @ComputerID
	  AND	UserID = @UserID
	  AND	SoftwareID = @SoftwareID
	  AND	SoftwareDetailsID = @SoftwareDetailsID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[SoftwareOccurrenceRemoveAllByComputerIDUserID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[SoftwareOccurrenceRemoveAllByComputerIDUserID]
GO
CREATE PROCEDURE [dbo].[SoftwareOccurrenceRemoveAllByComputerIDUserID]
	@ComputerID		int,
	@UserID			int
AS
	DELETE	[dbo].[SoftwareOccurrence]
	WHERE	ComputerID = @ComputerID
	  AND	UserID = @UserID
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[SoftwareOccurrenceRemoveAll]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[SoftwareOccurrenceRemoveAll]
GO
CREATE PROCEDURE [dbo].[SoftwareOccurrenceRemoveAll]
	
AS
	DELETE	[dbo].[SoftwareOccurrence]
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[SoftwareOccurrenceReplaceSubsetByComputerIDUserID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[SoftwareOccurrenceReplaceSubsetByComputerIDUserID]
GO
-- Replace the record subset selected by (@ComputerID, @UserID)
-- using unique identifier (ComputerID, UserID, SoftwareID, SoftwareDetailsID)
-- updating fields (Evidence, PackagePathID, PolicyGUID, InstallationDate)
CREATE PROCEDURE [dbo].[SoftwareOccurrenceReplaceSubsetByComputerIDUserID]
	@ComputerID		int,
	@UserID			int
AS
	DECLARE @count AS int
	SET @count = 0

	CREATE INDEX [TempSoftwareOccurrenceByComputerIDUserID]
		ON #SoftwareOccurrence (ComputerID, UserID, SoftwareID, SoftwareDetailsID)

	BEGIN TRANSACTION
	DELETE [SoftwareOccurrence]
		WHERE	ComputerID = @ComputerID
		  AND	UserID = @UserID
		AND NOT EXISTS(		-- Replacement record doesn't exist
			SELECT * FROM #SoftwareOccurrence AS t
			WHERE	SoftwareOccurrence.ComputerID = t.ComputerID
			  AND	SoftwareOccurrence.UserID = t.UserID
			  AND	SoftwareOccurrence.SoftwareID = t.SoftwareID
			  AND	SoftwareOccurrence.SoftwareDetailsID = t.SoftwareDetailsID
		)

	UPDATE [dbo].[SoftwareOccurrence]
		SET	Evidence = t.Evidence,
			PackagePathID = t.PackagePathID,
			PolicyGUID = t.PolicyGUID,
			InstallationDate = t.InstallationDate
		FROM	#SoftwareOccurrence AS t
		WHERE	SoftwareOccurrence.ComputerID = t.ComputerID
		  AND	SoftwareOccurrence.UserID = t.UserID
		  AND	SoftwareOccurrence.SoftwareID = t.SoftwareID
		  AND	SoftwareOccurrence.SoftwareDetailsID = t.SoftwareDetailsID
	SET @count = @@ROWCOUNT

	INSERT [SoftwareOccurrence] (
		ComputerID,
		UserID,
		SoftwareID,
		SoftwareDetailsID,
		Evidence,
		PackagePathID,
		PolicyGUID,
		InstallationDate
	)
		SELECT	ComputerID,
			UserID,
			SoftwareID,
			SoftwareDetailsID,
			Evidence,
			PackagePathID,
			PolicyGUID,
			InstallationDate
		FROM	#SoftwareOccurrence AS t
		WHERE NOT EXISTS(	-- Current record doesn't exist
			SELECT * FROM [SoftwareOccurrence]
			WHERE	SoftwareOccurrence.ComputerID = t.ComputerID
			  AND	SoftwareOccurrence.UserID = t.UserID
			  AND	SoftwareOccurrence.SoftwareID = t.SoftwareID
			  AND	SoftwareOccurrence.SoftwareDetailsID = t.SoftwareDetailsID
		)
	SET @count = @count + @@ROWCOUNT
	DROP TABLE #SoftwareOccurrence	-- Drop the temporary table
	COMMIT WORK
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[SoftwarePropertyGetByProperty]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[SoftwarePropertyGetByProperty]
GO
CREATE PROCEDURE [dbo].[SoftwarePropertyGetByProperty]
	@Property		nvarchar(256)
AS
	SELECT	SoftwarePropertyID,
		Property
	FROM	[dbo].[SoftwareProperty]
	WHERE	Property = @Property
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[SoftwarePropertyGetByID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[SoftwarePropertyGetByID]
GO
CREATE PROCEDURE [dbo].[SoftwarePropertyGetByID]
	@SoftwarePropertyID	int
AS
	SELECT	SoftwarePropertyID,
		Property
	FROM	[dbo].[SoftwareProperty]
	WHERE	SoftwarePropertyID = @SoftwarePropertyID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[SoftwarePropertyGetAll]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[SoftwarePropertyGetAll]
GO
CREATE PROCEDURE [dbo].[SoftwarePropertyGetAll]
AS
	SELECT	SoftwarePropertyID,
		Property
	FROM	[dbo].[SoftwareProperty]
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[SoftwarePropertyAdd]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[SoftwarePropertyAdd]
GO
CREATE PROCEDURE [dbo].[SoftwarePropertyAdd]
	@Property		nvarchar(256)
AS
	INSERT INTO  dbo.SoftwareProperty (
		Property
	)
	VALUES (
		@Property
	)
	RETURN SCOPE_IDENTITY()
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[SoftwarePropertyBind]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[SoftwarePropertyBind]
GO
CREATE PROCEDURE [dbo].[SoftwarePropertyBind]
	@Property		nvarchar(256)
AS
	DECLARE	@ID	int

	SELECT	@ID = SoftwarePropertyID
	FROM	[dbo].[SoftwareProperty]
	WHERE	Property = @Property

	IF @ID IS NULL
		EXEC @ID = SoftwarePropertyAdd @Property

	RETURN @ID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[SoftwarePropertySchema]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[SoftwarePropertySchema]
GO
CREATE PROCEDURE [dbo].[SoftwarePropertySchema]
AS
	SELECT
	'IF OBJECT_ID(''tempdb..#SoftwareProperty'') IS NULL' + CAST(0x0A AS CHAR(1)) +
	'	CREATE TABLE #SoftwareProperty (' + CAST(0x0A AS CHAR(1)) +
	'		SoftwarePropertyID	int NULL,' + CAST(0x0A AS CHAR(1)) +
	'		Property		nvarchar(256) COLLATE database_default NOT NULL' + CAST(0x0A AS CHAR(1)) +
	'	)' + CAST(0x0A AS CHAR(1)) +
	'ELSE' + CAST(0x0A AS CHAR(1)) +
	'	DELETE FROM #SoftwareProperty' + CAST(0x0A AS CHAR(1)) +
	'' AS SQL
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[SoftwarePropertyTempAdd]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[SoftwarePropertyTempAdd]
GO
CREATE PROCEDURE dbo.[SoftwarePropertyTempAdd]
	@SoftwarePropertyID	int,
	@Property		nvarchar(256)
AS
	INSERT INTO #SoftwareProperty (
		SoftwarePropertyID,
		Property
	)
	VALUES (
		@SoftwarePropertyID,
		@Property
	)
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[SoftwarePropertyAddBatch]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[SoftwarePropertyAddBatch]
GO
CREATE PROCEDURE dbo.[SoftwarePropertyAddBatch]
AS
	DECLARE @count int
	INSERT dbo.SoftwareProperty (
		Property
	)
		SELECT	Property
		FROM #SoftwareProperty
	SET @count = @@ROWCOUNT
	DROP TABLE #SoftwareProperty	-- Drop temporary table
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[SoftwarePropertyUpdateByID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[SoftwarePropertyUpdateByID]
GO
CREATE PROCEDURE [dbo].[SoftwarePropertyUpdateByID]
	@SoftwarePropertyID	int,
	@Property		nvarchar(256)
AS
	DECLARE	@ID	int
	SET @ID = 0

	UPDATE	[dbo].[SoftwareProperty]
	SET	@ID = SoftwarePropertyID,
		Property = @Property
	WHERE	SoftwarePropertyID = @SoftwarePropertyID
	RETURN @ID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[SoftwarePropertyUpdateBatchByID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[SoftwarePropertyUpdateBatchByID]
GO
CREATE PROCEDURE dbo.[SoftwarePropertyUpdateBatchByID]
AS
	DECLARE @count int

	CREATE INDEX [TempSoftwarePropertyID]
		ON #SoftwareProperty (SoftwarePropertyID)

	UPDATE	[dbo].[SoftwareProperty]
	SET	Property = t.Property
	FROM	#SoftwareProperty AS t
	WHERE	SoftwareProperty.SoftwarePropertyID = t.SoftwarePropertyID
	SET @count = @@ROWCOUNT
	DROP TABLE #SoftwareProperty	-- Drop the temporary table
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[SoftwarePropertyPutByProperty]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[SoftwarePropertyPutByProperty]
GO
CREATE PROCEDURE [dbo].[SoftwarePropertyPutByProperty]
	@Property		nvarchar(256)
AS
	DECLARE @ID	int

	SELECT	@ID = SoftwarePropertyID
	FROM	SoftwareProperty
	WHERE	Property = @Property

	IF @ID IS NULL
		EXEC @ID = SoftwarePropertyAdd @Property

	RETURN @ID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[SoftwarePropertyPutBatchByProperty]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[SoftwarePropertyPutBatchByProperty]
GO
CREATE PROCEDURE [dbo].[SoftwarePropertyPutBatchByProperty]
AS
	DECLARE @count AS int
	SET @count = 0

	CREATE INDEX [TempSoftwarePropertyProperty]
		ON #SoftwareProperty (Property)

	BEGIN TRANSACTION

	INSERT [dbo].[SoftwareProperty] (
		Property
	)
		SELECT	Property
		FROM	#SoftwareProperty AS t
		WHERE NOT EXISTS(	-- Current record doesn't exist
			SELECT * FROM [dbo].[SoftwareProperty]
			WHERE	SoftwareProperty.Property = t.Property
		)
	SET @count = @count + @@ROWCOUNT
	DROP TABLE #SoftwareProperty	-- Drop the temporary table
	COMMIT WORK
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[SoftwarePropertyRemoveBatch]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[SoftwarePropertyRemoveBatch]
GO

CREATE PROCEDURE [dbo].[SoftwarePropertyRemoveBatch]
AS

	CREATE INDEX [TempSoftwarePropertySoftwarePropertyRemoveBatch]
		ON #SoftwareProperty (SoftwarePropertyID)	

	-- Delete records from SoftwareProperty identified by fields of [TempSoftwarePropertySoftwarePropertyRemoveBatch]
	DELETE [dbo].[SoftwareProperty]
	WHERE EXISTS(
			SELECT * FROM #SoftwareProperty AS t
			WHERE	SoftwareProperty.SoftwarePropertyID = t.SoftwarePropertyID
		)
	DROP TABLE #SoftwareProperty      -- Drop the temporary table
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[SoftwarePropertyRemoveByProperty]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[SoftwarePropertyRemoveByProperty]
GO
CREATE PROCEDURE [dbo].[SoftwarePropertyRemoveByProperty]
	@Property		nvarchar(256)
AS
	-- SoftwareProperty deletes cascade to:
	--	SoftwareValue by FK_SoftwareValue_SoftwareProperty
	DELETE	[dbo].[SoftwareProperty]
	WHERE	Property = @Property
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[SoftwarePropertyRemoveAll]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[SoftwarePropertyRemoveAll]
GO
CREATE PROCEDURE [dbo].[SoftwarePropertyRemoveAll]
	
AS
	DELETE	[dbo].[SoftwareProperty]
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[SoftwareValueGetBySoftwareOccurrenceIDSoftwarePropertyID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[SoftwareValueGetBySoftwareOccurrenceIDSoftwarePropertyID]
GO
CREATE PROCEDURE [dbo].[SoftwareValueGetBySoftwareOccurrenceIDSoftwarePropertyID]
	@SoftwareOccurrenceID	int,
	@SoftwarePropertyID	int
AS
	SELECT	SoftwareOccurrenceID,
		SoftwarePropertyID,
		Value
	FROM	[dbo].[SoftwareValue]
	WHERE	SoftwareOccurrenceID = @SoftwareOccurrenceID
	  AND	SoftwarePropertyID = @SoftwarePropertyID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[SoftwareValueGetAllBySoftwareOccurrenceID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[SoftwareValueGetAllBySoftwareOccurrenceID]
GO
CREATE PROCEDURE [dbo].[SoftwareValueGetAllBySoftwareOccurrenceID]
	@SoftwareOccurrenceID	int
AS
	SELECT	SoftwareOccurrenceID,
		SoftwarePropertyID,
		Value
	FROM	[dbo].[SoftwareValue]
	WHERE	SoftwareOccurrenceID = @SoftwareOccurrenceID
	ORDER BY SoftwarePropertyID
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[SoftwareValueGetAll]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[SoftwareValueGetAll]
GO
CREATE PROCEDURE [dbo].[SoftwareValueGetAll]
AS
	SELECT	SoftwareOccurrenceID,
		SoftwarePropertyID,
		Value
	FROM	[dbo].[SoftwareValue]
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[SoftwareValueAdd]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[SoftwareValueAdd]
GO
CREATE PROCEDURE [dbo].[SoftwareValueAdd]
	@SoftwareOccurrenceID	int,
	@SoftwarePropertyID	int,
	@Value			nvarchar(256) = NULL
AS
	INSERT INTO  dbo.SoftwareValue (
		SoftwareOccurrenceID,
		SoftwarePropertyID,
		Value
	)
	VALUES (
		@SoftwareOccurrenceID,
		@SoftwarePropertyID,
		@Value
	)
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[SoftwareValueSchema]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[SoftwareValueSchema]
GO
CREATE PROCEDURE [dbo].[SoftwareValueSchema]
AS
	SELECT
	'IF OBJECT_ID(''tempdb..#SoftwareValue'') IS NULL' + CAST(0x0A AS CHAR(1)) +
	'	CREATE TABLE #SoftwareValue (' + CAST(0x0A AS CHAR(1)) +
	'		SoftwareOccurrenceID	int NOT NULL,' + CAST(0x0A AS CHAR(1)) +
	'		SoftwarePropertyID	int NOT NULL,' + CAST(0x0A AS CHAR(1)) +
	'		Value			nvarchar(256) COLLATE database_default NULL' + CAST(0x0A AS CHAR(1)) +
	'	)' + CAST(0x0A AS CHAR(1)) +
	'ELSE' + CAST(0x0A AS CHAR(1)) +
	'	DELETE FROM #SoftwareValue' + CAST(0x0A AS CHAR(1)) +
	'' AS SQL
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[SoftwareValueTempAdd]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[SoftwareValueTempAdd]
GO
CREATE PROCEDURE dbo.[SoftwareValueTempAdd]
	@SoftwareOccurrenceID	int,
	@SoftwarePropertyID	int,
	@Value			nvarchar(256) = NULL
AS
	INSERT INTO #SoftwareValue (
		SoftwareOccurrenceID,
		SoftwarePropertyID,
		Value
	)
	VALUES (
		@SoftwareOccurrenceID,
		@SoftwarePropertyID,
		@Value
	)
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[SoftwareValueAddBatch]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[SoftwareValueAddBatch]
GO
CREATE PROCEDURE dbo.[SoftwareValueAddBatch]
AS
	DECLARE @count int
	INSERT dbo.SoftwareValue (
		SoftwareOccurrenceID,
		SoftwarePropertyID,
		Value
	)
		SELECT	SoftwareOccurrenceID,
			SoftwarePropertyID,
			Value
		FROM #SoftwareValue
	SET @count = @@ROWCOUNT
	DROP TABLE #SoftwareValue	-- Drop temporary table
	RETURN @count
GO

/*
Add new SoftwareValue bound to
	SoftwareProperty using Property
	with SoftwareOccurrenceID, Value
*/

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[SoftwareValueUpdateBySoftwareOccurrenceIDSoftwarePropertyID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[SoftwareValueUpdateBySoftwareOccurrenceIDSoftwarePropertyID]
GO
CREATE PROCEDURE [dbo].[SoftwareValueUpdateBySoftwareOccurrenceIDSoftwarePropertyID]
	@SoftwareOccurrenceID	int,
	@SoftwarePropertyID	int,
	@Value			nvarchar(256) = NULL
AS
	UPDATE	[dbo].[SoftwareValue]
	SET	Value = @Value
	WHERE	SoftwareOccurrenceID = @SoftwareOccurrenceID
	  AND	SoftwarePropertyID = @SoftwarePropertyID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[SoftwareValueUpdateBatchBySoftwareOccurrenceIDSoftwarePropertyID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[SoftwareValueUpdateBatchBySoftwareOccurrenceIDSoftwarePropertyID]
GO
CREATE PROCEDURE dbo.[SoftwareValueUpdateBatchBySoftwareOccurrenceIDSoftwarePropertyID]
AS
	DECLARE @count int

	CREATE INDEX [TempSoftwareValueSoftwareOccurrenceIDSoftwarePropertyID]
		ON #SoftwareValue (SoftwareOccurrenceID, SoftwarePropertyID)

	UPDATE	[dbo].[SoftwareValue]
	SET	Value = t.Value
	FROM	#SoftwareValue AS t
	WHERE	SoftwareValue.SoftwareOccurrenceID = t.SoftwareOccurrenceID
	  AND	SoftwareValue.SoftwarePropertyID = t.SoftwarePropertyID
	SET @count = @@ROWCOUNT
	DROP TABLE #SoftwareValue	-- Drop the temporary table
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[SoftwareValuePutBySoftwareOccurrenceIDSoftwarePropertyID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[SoftwareValuePutBySoftwareOccurrenceIDSoftwarePropertyID]
GO
CREATE PROCEDURE [dbo].[SoftwareValuePutBySoftwareOccurrenceIDSoftwarePropertyID]
	@SoftwareOccurrenceID	int,
	@SoftwarePropertyID	int,
	@Value			nvarchar(256) = NULL
AS
	IF NOT EXISTS(
		SELECT	1
		FROM	dbo.SoftwareValue
		WHERE	SoftwareOccurrenceID = @SoftwareOccurrenceID
		  AND	SoftwarePropertyID = @SoftwarePropertyID
	)
		EXEC SoftwareValueAdd @SoftwareOccurrenceID,
			@SoftwarePropertyID,
			@Value
	ELSE
		EXEC SoftwareValueUpdateBySoftwareOccurrenceIDSoftwarePropertyID @SoftwareOccurrenceID,
			@SoftwarePropertyID,
			@Value
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[SoftwareValuePutBatchBySoftwareOccurrenceIDSoftwarePropertyID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[SoftwareValuePutBatchBySoftwareOccurrenceIDSoftwarePropertyID]
GO
CREATE PROCEDURE [dbo].[SoftwareValuePutBatchBySoftwareOccurrenceIDSoftwarePropertyID]
AS
	DECLARE @count AS int
	SET @count = 0

	CREATE INDEX [TempSoftwareValueSoftwareOccurrenceIDSoftwarePropertyID]
		ON #SoftwareValue (SoftwareOccurrenceID, SoftwarePropertyID)

	BEGIN TRANSACTION
	UPDATE [dbo].[SoftwareValue]
		SET	Value = t.Value
		FROM	#SoftwareValue AS t
		WHERE	SoftwareValue.SoftwareOccurrenceID = t.SoftwareOccurrenceID
		  AND	SoftwareValue.SoftwarePropertyID = t.SoftwarePropertyID
	SET @count = @@ROWCOUNT

	INSERT [dbo].[SoftwareValue] (
		SoftwareOccurrenceID,
		SoftwarePropertyID,
		Value
	)
		SELECT	SoftwareOccurrenceID,
			SoftwarePropertyID,
			Value
		FROM	#SoftwareValue AS t
		WHERE NOT EXISTS(	-- Current record doesn't exist
			SELECT * FROM [dbo].[SoftwareValue]
			WHERE	SoftwareValue.SoftwareOccurrenceID = t.SoftwareOccurrenceID
			  AND	SoftwareValue.SoftwarePropertyID = t.SoftwarePropertyID
		)
	SET @count = @count + @@ROWCOUNT
	DROP TABLE #SoftwareValue	-- Drop the temporary table
	COMMIT WORK
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[SoftwareValueRemoveBatch]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[SoftwareValueRemoveBatch]
GO

CREATE PROCEDURE [dbo].[SoftwareValueRemoveBatch]
AS

	CREATE INDEX [TempSoftwareValueSoftwareValueRemoveBatch]
		ON #SoftwareValue (SoftwareOccurrenceID, SoftwarePropertyID)	

	-- Delete records from SoftwareValue identified by fields of [TempSoftwareValueSoftwareValueRemoveBatch]
	DELETE [dbo].[SoftwareValue]
	WHERE EXISTS(
			SELECT * FROM #SoftwareValue AS t
			WHERE	SoftwareValue.SoftwareOccurrenceID = t.SoftwareOccurrenceID
			  AND	SoftwareValue.SoftwarePropertyID = t.SoftwarePropertyID
		)
	DROP TABLE #SoftwareValue      -- Drop the temporary table
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[SoftwareValueRemoveBySoftwareOccurrenceIDSoftwarePropertyID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[SoftwareValueRemoveBySoftwareOccurrenceIDSoftwarePropertyID]
GO
CREATE PROCEDURE [dbo].[SoftwareValueRemoveBySoftwareOccurrenceIDSoftwarePropertyID]
	@SoftwareOccurrenceID	int,
	@SoftwarePropertyID	int
AS
	DELETE	[dbo].[SoftwareValue]
	WHERE	SoftwareOccurrenceID = @SoftwareOccurrenceID
	  AND	SoftwarePropertyID = @SoftwarePropertyID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[SoftwareValueRemoveAllBySoftwareOccurrenceID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[SoftwareValueRemoveAllBySoftwareOccurrenceID]
GO
CREATE PROCEDURE [dbo].[SoftwareValueRemoveAllBySoftwareOccurrenceID]
	@SoftwareOccurrenceID	int
AS
	DELETE	[dbo].[SoftwareValue]
	WHERE	SoftwareOccurrenceID = @SoftwareOccurrenceID
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[SoftwareValueRemoveAll]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[SoftwareValueRemoveAll]
GO
CREATE PROCEDURE [dbo].[SoftwareValueRemoveAll]
	
AS
	DELETE	[dbo].[SoftwareValue]
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[SoftwareValueReplaceSubsetBySoftwareOccurrenceID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[SoftwareValueReplaceSubsetBySoftwareOccurrenceID]
GO
-- Replace the record subset selected by (@SoftwareOccurrenceID)
-- using unique identifier (SoftwareOccurrenceID, SoftwarePropertyID)
-- updating fields (Value)
CREATE PROCEDURE [dbo].[SoftwareValueReplaceSubsetBySoftwareOccurrenceID]
	@SoftwareOccurrenceID	int
AS
	DECLARE @count AS int
	SET @count = 0

	CREATE INDEX [TempSoftwareValueBySoftwareOccurrenceID]
		ON #SoftwareValue (SoftwareOccurrenceID, SoftwarePropertyID)

	BEGIN TRANSACTION
	DELETE [SoftwareValue]
		WHERE	SoftwareOccurrenceID = @SoftwareOccurrenceID
		AND NOT EXISTS(		-- Replacement record doesn't exist
			SELECT * FROM #SoftwareValue AS t
			WHERE	SoftwareValue.SoftwareOccurrenceID = t.SoftwareOccurrenceID
			  AND	SoftwareValue.SoftwarePropertyID = t.SoftwarePropertyID
		)

	UPDATE [dbo].[SoftwareValue]
		SET	Value = t.Value
		FROM	#SoftwareValue AS t
		WHERE	SoftwareValue.SoftwareOccurrenceID = t.SoftwareOccurrenceID
		  AND	SoftwareValue.SoftwarePropertyID = t.SoftwarePropertyID
	SET @count = @@ROWCOUNT

	INSERT [SoftwareValue] (
		SoftwareOccurrenceID,
		SoftwarePropertyID,
		Value
	)
		SELECT	SoftwareOccurrenceID,
			SoftwarePropertyID,
			Value
		FROM	#SoftwareValue AS t
		WHERE NOT EXISTS(	-- Current record doesn't exist
			SELECT * FROM [SoftwareValue]
			WHERE	SoftwareValue.SoftwareOccurrenceID = t.SoftwareOccurrenceID
			  AND	SoftwareValue.SoftwarePropertyID = t.SoftwarePropertyID
		)
	SET @count = @count + @@ROWCOUNT
	DROP TABLE #SoftwareValue	-- Drop the temporary table
	COMMIT WORK
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[SoftwareFilePathGetByPath]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[SoftwareFilePathGetByPath]
GO
CREATE PROCEDURE [dbo].[SoftwareFilePathGetByPath]
	@Path			nvarchar(400)
AS
	SELECT	SoftwareFilePathID,
		Path
	FROM	[dbo].[SoftwareFilePath]
	WHERE	Path = @Path
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[SoftwareFilePathGetByID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[SoftwareFilePathGetByID]
GO
CREATE PROCEDURE [dbo].[SoftwareFilePathGetByID]
	@SoftwareFilePathID	int
AS
	SELECT	SoftwareFilePathID,
		Path
	FROM	[dbo].[SoftwareFilePath]
	WHERE	SoftwareFilePathID = @SoftwareFilePathID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[SoftwareFilePathGetAll]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[SoftwareFilePathGetAll]
GO
CREATE PROCEDURE [dbo].[SoftwareFilePathGetAll]
AS
	SELECT	SoftwareFilePathID,
		Path
	FROM	[dbo].[SoftwareFilePath]
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[SoftwareFilePathAdd]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[SoftwareFilePathAdd]
GO
CREATE PROCEDURE [dbo].[SoftwareFilePathAdd]
	@Path			nvarchar(400)
AS
	INSERT INTO  dbo.SoftwareFilePath (
		Path
	)
	VALUES (
		@Path
	)
	RETURN SCOPE_IDENTITY()
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[SoftwareFilePathBind]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[SoftwareFilePathBind]
GO
CREATE PROCEDURE [dbo].[SoftwareFilePathBind]
	@Path			nvarchar(400)
AS
	DECLARE	@ID	int

	SELECT	@ID = SoftwareFilePathID
	FROM	[dbo].[SoftwareFilePath]
	WHERE	Path = @Path

	IF @ID IS NULL
		EXEC @ID = SoftwareFilePathAdd @Path

	RETURN @ID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[SoftwareFilePathSchema]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[SoftwareFilePathSchema]
GO
CREATE PROCEDURE [dbo].[SoftwareFilePathSchema]
AS
	SELECT
	'IF OBJECT_ID(''tempdb..#SoftwareFilePath'') IS NULL' + CAST(0x0A AS CHAR(1)) +
	'	CREATE TABLE #SoftwareFilePath (' + CAST(0x0A AS CHAR(1)) +
	'		SoftwareFilePathID	int NULL,' + CAST(0x0A AS CHAR(1)) +
	'		Path			nvarchar(400) COLLATE database_default NOT NULL' + CAST(0x0A AS CHAR(1)) +
	'	)' + CAST(0x0A AS CHAR(1)) +
	'ELSE' + CAST(0x0A AS CHAR(1)) +
	'	DELETE FROM #SoftwareFilePath' + CAST(0x0A AS CHAR(1)) +
	'' AS SQL
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[SoftwareFilePathTempAdd]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[SoftwareFilePathTempAdd]
GO
CREATE PROCEDURE dbo.[SoftwareFilePathTempAdd]
	@SoftwareFilePathID	int,
	@Path			nvarchar(400)
AS
	INSERT INTO #SoftwareFilePath (
		SoftwareFilePathID,
		Path
	)
	VALUES (
		@SoftwareFilePathID,
		@Path
	)
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[SoftwareFilePathAddBatch]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[SoftwareFilePathAddBatch]
GO
CREATE PROCEDURE dbo.[SoftwareFilePathAddBatch]
AS
	DECLARE @count int
	INSERT dbo.SoftwareFilePath (
		Path
	)
		SELECT	Path
		FROM #SoftwareFilePath
	SET @count = @@ROWCOUNT
	DROP TABLE #SoftwareFilePath	-- Drop temporary table
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[SoftwareFilePathUpdateByID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[SoftwareFilePathUpdateByID]
GO
CREATE PROCEDURE [dbo].[SoftwareFilePathUpdateByID]
	@SoftwareFilePathID	int,
	@Path			nvarchar(400)
AS
	DECLARE	@ID	int
	SET @ID = 0

	UPDATE	[dbo].[SoftwareFilePath]
	SET	@ID = SoftwareFilePathID,
		Path = @Path
	WHERE	SoftwareFilePathID = @SoftwareFilePathID
	RETURN @ID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[SoftwareFilePathUpdateBatchByID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[SoftwareFilePathUpdateBatchByID]
GO
CREATE PROCEDURE dbo.[SoftwareFilePathUpdateBatchByID]
AS
	DECLARE @count int

	CREATE INDEX [TempSoftwareFilePathID]
		ON #SoftwareFilePath (SoftwareFilePathID)

	UPDATE	[dbo].[SoftwareFilePath]
	SET	Path = t.Path
	FROM	#SoftwareFilePath AS t
	WHERE	SoftwareFilePath.SoftwareFilePathID = t.SoftwareFilePathID
	SET @count = @@ROWCOUNT
	DROP TABLE #SoftwareFilePath	-- Drop the temporary table
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[SoftwareFilePathPutByPath]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[SoftwareFilePathPutByPath]
GO
CREATE PROCEDURE [dbo].[SoftwareFilePathPutByPath]
	@Path			nvarchar(400)
AS
	DECLARE @ID	int

	SELECT	@ID = SoftwareFilePathID
	FROM	SoftwareFilePath
	WHERE	Path = @Path

	IF @ID IS NULL
		EXEC @ID = SoftwareFilePathAdd @Path

	RETURN @ID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[SoftwareFilePathPutBatchByPath]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[SoftwareFilePathPutBatchByPath]
GO
CREATE PROCEDURE [dbo].[SoftwareFilePathPutBatchByPath]
AS
	DECLARE @count AS int
	SET @count = 0

	CREATE INDEX [TempSoftwareFilePathPath]
		ON #SoftwareFilePath (Path)

	BEGIN TRANSACTION

	INSERT [dbo].[SoftwareFilePath] (
		Path
	)
		SELECT	Path
		FROM	#SoftwareFilePath AS t
		WHERE NOT EXISTS(	-- Current record doesn't exist
			SELECT * FROM [dbo].[SoftwareFilePath]
			WHERE	SoftwareFilePath.Path = t.Path
		)
	SET @count = @count + @@ROWCOUNT
	DROP TABLE #SoftwareFilePath	-- Drop the temporary table
	COMMIT WORK
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[SoftwareFilePathRemoveBatch]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[SoftwareFilePathRemoveBatch]
GO

CREATE PROCEDURE [dbo].[SoftwareFilePathRemoveBatch]
AS

	CREATE INDEX [TempSoftwareFilePathSoftwareFilePathRemoveBatch]
		ON #SoftwareFilePath (SoftwareFilePathID)	

	-- Delete records from SoftwareFilePath identified by fields of [TempSoftwareFilePathSoftwareFilePathRemoveBatch]
	DELETE [dbo].[SoftwareFilePath]
	WHERE EXISTS(
			SELECT * FROM #SoftwareFilePath AS t
			WHERE	SoftwareFilePath.SoftwareFilePathID = t.SoftwareFilePathID
		)
	DROP TABLE #SoftwareFilePath      -- Drop the temporary table
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[SoftwareFilePathRemoveByID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[SoftwareFilePathRemoveByID]
GO
CREATE PROCEDURE [dbo].[SoftwareFilePathRemoveByID]
	@SoftwareFilePathID	int
AS
	-- SoftwareFilePath deletes cascade to:
	--	SoftwareFile by FK_SoftwareFile_SoftwareFilePath
	--		SoftwareFileProperty by FK_SoftwareFileProperty_SoftwareFile
	DELETE	[dbo].[SoftwareFilePath]
	WHERE	SoftwareFilePathID = @SoftwareFilePathID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[SoftwareFilePathRemoveAll]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[SoftwareFilePathRemoveAll]
GO
CREATE PROCEDURE [dbo].[SoftwareFilePathRemoveAll]
	
AS
	DELETE	[dbo].[SoftwareFilePath]
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[SoftwareFileNameGetByName]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[SoftwareFileNameGetByName]
GO
CREATE PROCEDURE [dbo].[SoftwareFileNameGetByName]
	@Name			nvarchar(400)
AS
	SELECT	SoftwareFileNameID,
		[Name]
	FROM	[dbo].[SoftwareFileName]
	WHERE	[Name] = @Name
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[SoftwareFileNameGetByID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[SoftwareFileNameGetByID]
GO
CREATE PROCEDURE [dbo].[SoftwareFileNameGetByID]
	@SoftwareFileNameID	int
AS
	SELECT	SoftwareFileNameID,
		[Name]
	FROM	[dbo].[SoftwareFileName]
	WHERE	SoftwareFileNameID = @SoftwareFileNameID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[SoftwareFileNameGetAll]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[SoftwareFileNameGetAll]
GO
CREATE PROCEDURE [dbo].[SoftwareFileNameGetAll]
AS
	SELECT	SoftwareFileNameID,
		[Name]
	FROM	[dbo].[SoftwareFileName]
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[SoftwareFileNameAdd]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[SoftwareFileNameAdd]
GO
CREATE PROCEDURE [dbo].[SoftwareFileNameAdd]
	@Name			nvarchar(400)
AS
	INSERT INTO  dbo.SoftwareFileName (
		[Name]
	)
	VALUES (
		@Name
	)
	RETURN SCOPE_IDENTITY()
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[SoftwareFileNameBind]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[SoftwareFileNameBind]
GO
CREATE PROCEDURE [dbo].[SoftwareFileNameBind]
	@Name			nvarchar(400)
AS
	DECLARE	@ID	int

	SELECT	@ID = SoftwareFileNameID
	FROM	[dbo].[SoftwareFileName]
	WHERE	[Name] = @Name

	IF @ID IS NULL
		EXEC @ID = SoftwareFileNameAdd @Name

	RETURN @ID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[SoftwareFileNameSchema]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[SoftwareFileNameSchema]
GO
CREATE PROCEDURE [dbo].[SoftwareFileNameSchema]
AS
	SELECT
	'IF OBJECT_ID(''tempdb..#SoftwareFileName'') IS NULL' + CAST(0x0A AS CHAR(1)) +
	'	CREATE TABLE #SoftwareFileName (' + CAST(0x0A AS CHAR(1)) +
	'		SoftwareFileNameID	int NULL,' + CAST(0x0A AS CHAR(1)) +
	'		[Name]			nvarchar(400) COLLATE database_default NOT NULL' + CAST(0x0A AS CHAR(1)) +
	'	)' + CAST(0x0A AS CHAR(1)) +
	'ELSE' + CAST(0x0A AS CHAR(1)) +
	'	DELETE FROM #SoftwareFileName' + CAST(0x0A AS CHAR(1)) +
	'' AS SQL
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[SoftwareFileNameTempAdd]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[SoftwareFileNameTempAdd]
GO
CREATE PROCEDURE dbo.[SoftwareFileNameTempAdd]
	@SoftwareFileNameID	int,
	@Name			nvarchar(400)
AS
	INSERT INTO #SoftwareFileName (
		SoftwareFileNameID,
		[Name]
	)
	VALUES (
		@SoftwareFileNameID,
		@Name
	)
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[SoftwareFileNameAddBatch]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[SoftwareFileNameAddBatch]
GO
CREATE PROCEDURE dbo.[SoftwareFileNameAddBatch]
AS
	DECLARE @count int
	INSERT dbo.SoftwareFileName (
		[Name]
	)
		SELECT	[Name]
		FROM #SoftwareFileName
	SET @count = @@ROWCOUNT
	DROP TABLE #SoftwareFileName	-- Drop temporary table
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[SoftwareFileNameUpdateByID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[SoftwareFileNameUpdateByID]
GO
CREATE PROCEDURE [dbo].[SoftwareFileNameUpdateByID]
	@SoftwareFileNameID	int,
	@Name			nvarchar(400)
AS
	DECLARE	@ID	int
	SET @ID = 0

	UPDATE	[dbo].[SoftwareFileName]
	SET	@ID = SoftwareFileNameID,
		[Name] = @Name
	WHERE	SoftwareFileNameID = @SoftwareFileNameID
	RETURN @ID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[SoftwareFileNameUpdateBatchByID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[SoftwareFileNameUpdateBatchByID]
GO
CREATE PROCEDURE dbo.[SoftwareFileNameUpdateBatchByID]
AS
	DECLARE @count int

	CREATE INDEX [TempSoftwareFileNameID]
		ON #SoftwareFileName (SoftwareFileNameID)

	UPDATE	[dbo].[SoftwareFileName]
	SET	[Name] = t.[Name]
	FROM	#SoftwareFileName AS t
	WHERE	SoftwareFileName.SoftwareFileNameID = t.SoftwareFileNameID
	SET @count = @@ROWCOUNT
	DROP TABLE #SoftwareFileName	-- Drop the temporary table
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[SoftwareFileNamePutByName]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[SoftwareFileNamePutByName]
GO
CREATE PROCEDURE [dbo].[SoftwareFileNamePutByName]
	@Name			nvarchar(400)
AS
	DECLARE @ID	int

	SELECT	@ID = SoftwareFileNameID
	FROM	SoftwareFileName
	WHERE	[Name] = @Name

	IF @ID IS NULL
		EXEC @ID = SoftwareFileNameAdd @Name

	RETURN @ID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[SoftwareFileNamePutBatchByName]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[SoftwareFileNamePutBatchByName]
GO
CREATE PROCEDURE [dbo].[SoftwareFileNamePutBatchByName]
AS
	DECLARE @count AS int
	SET @count = 0

	CREATE INDEX [TempSoftwareFileNameName]
		ON #SoftwareFileName ([Name])

	BEGIN TRANSACTION

	INSERT [dbo].[SoftwareFileName] (
		[Name]
	)
		SELECT	[Name]
		FROM	#SoftwareFileName AS t
		WHERE NOT EXISTS(	-- Current record doesn't exist
			SELECT * FROM [dbo].[SoftwareFileName]
			WHERE	SoftwareFileName.[Name] = t.[Name]
		)
	SET @count = @count + @@ROWCOUNT
	DROP TABLE #SoftwareFileName	-- Drop the temporary table
	COMMIT WORK
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[SoftwareFileNameRemoveBatch]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[SoftwareFileNameRemoveBatch]
GO

CREATE PROCEDURE [dbo].[SoftwareFileNameRemoveBatch]
AS

	CREATE INDEX [TempSoftwareFileNameSoftwareFileNameRemoveBatch]
		ON #SoftwareFileName (SoftwareFileNameID)	

	-- Delete records from SoftwareFileName identified by fields of [TempSoftwareFileNameSoftwareFileNameRemoveBatch]
	DELETE [dbo].[SoftwareFileName]
	WHERE EXISTS(
			SELECT * FROM #SoftwareFileName AS t
			WHERE	SoftwareFileName.SoftwareFileNameID = t.SoftwareFileNameID
		)
	DROP TABLE #SoftwareFileName      -- Drop the temporary table
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[SoftwareFileNameRemoveByID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[SoftwareFileNameRemoveByID]
GO
CREATE PROCEDURE [dbo].[SoftwareFileNameRemoveByID]
	@SoftwareFileNameID	int
AS
	-- SoftwareFileName deletes cascade to:
	--	SoftwareFile by FK_SoftwareFile_SoftwareFileName
	--		SoftwareFileProperty by FK_SoftwareFileProperty_SoftwareFile
	--	SoftwareFileUsage by FK_SoftwareFileUsage_SoftwareFileName
	--		SoftwareUsagePerWeek by FK_SoftwareUsagePerWeek_SoftwareFileUsage
	DELETE	[dbo].[SoftwareFileName]
	WHERE	SoftwareFileNameID = @SoftwareFileNameID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[SoftwareFileNameRemoveAll]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[SoftwareFileNameRemoveAll]
GO
CREATE PROCEDURE [dbo].[SoftwareFileNameRemoveAll]
	
AS
	DELETE	[dbo].[SoftwareFileName]
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[SoftwareFileGetByComputerIDSoftwareIDPathIDNameID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[SoftwareFileGetByComputerIDSoftwareIDPathIDNameID]
GO
CREATE PROCEDURE [dbo].[SoftwareFileGetByComputerIDSoftwareIDPathIDNameID]
	@ComputerID		int,
	@SoftwareID		int = NULL,
	@SoftwareFilePathID	int = NULL,
	@SoftwareFileNameID	int = NULL
AS
	SELECT	SoftwareFileID,
		ComputerID,
		SoftwareID,
		Version,
		MD5,
		[Size],
		[DateTime],
		FileVersion,
		FileDescription,
		Language,
		CompanyName,
		SoftwareFilePathID,
		SoftwareFileNameID
	FROM	[dbo].[SoftwareFile]
	WHERE	ComputerID = @ComputerID
	  AND	(SoftwareID = @SoftwareID OR (SoftwareID IS NULL AND @SoftwareID IS NULL))
	  AND	(SoftwareFilePathID = @SoftwareFilePathID OR (SoftwareFilePathID IS NULL AND @SoftwareFilePathID IS NULL))
	  AND	(SoftwareFileNameID = @SoftwareFileNameID OR (SoftwareFileNameID IS NULL AND @SoftwareFileNameID IS NULL))
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[SoftwareFileGetAllByComputerID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[SoftwareFileGetAllByComputerID]
GO
CREATE PROCEDURE [dbo].[SoftwareFileGetAllByComputerID]
	@ComputerID		int
AS
	SELECT	SoftwareFileID,
		ComputerID,
		SoftwareID,
		Version,
		MD5,
		[Size],
		[DateTime],
		FileVersion,
		FileDescription,
		Language,
		CompanyName,
		SoftwareFilePathID,
		SoftwareFileNameID
	FROM	[dbo].[SoftwareFile]
	WHERE	ComputerID = @ComputerID
	ORDER BY SoftwareID, SoftwareFilePathID, SoftwareFileNameID
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[SoftwareFileGetAll]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[SoftwareFileGetAll]
GO
CREATE PROCEDURE [dbo].[SoftwareFileGetAll]
AS
	SELECT	SoftwareFileID,
		ComputerID,
		SoftwareID,
		Version,
		MD5,
		[Size],
		[DateTime],
		FileVersion,
		FileDescription,
		Language,
		CompanyName,
		SoftwareFilePathID,
		SoftwareFileNameID
	FROM	[dbo].[SoftwareFile]
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[SoftwareFileAdd]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[SoftwareFileAdd]
GO
CREATE PROCEDURE [dbo].[SoftwareFileAdd]
	@ComputerID		int,
	@SoftwareID		int = NULL,
	@Version		nvarchar(32) = NULL,
	@MD5			varchar(32),
	@Size			int,
	@DateTime		datetime = NULL,
	@FileVersion		nvarchar(256) = NULL,
	@FileDescription	nvarchar(256) = NULL,
	@Language		nvarchar(256) = NULL,
	@CompanyName		nvarchar(256) = NULL,
	@SoftwareFilePathID	int = NULL,
	@SoftwareFileNameID	int = NULL
AS
	INSERT INTO  dbo.SoftwareFile (
		ComputerID,
		SoftwareID,
		Version,
		MD5,
		[Size],
		[DateTime],
		FileVersion,
		FileDescription,
		Language,
		CompanyName,
		SoftwareFilePathID,
		SoftwareFileNameID
	)
	VALUES (
		@ComputerID,
		@SoftwareID,
		@Version,
		@MD5,
		@Size,
		@DateTime,
		@FileVersion,
		@FileDescription,
		@Language,
		@CompanyName,
		@SoftwareFilePathID,
		@SoftwareFileNameID
	)
	RETURN SCOPE_IDENTITY()
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[SoftwareFileBind]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[SoftwareFileBind]
GO
CREATE PROCEDURE [dbo].[SoftwareFileBind]
	@ComputerID		int,
	@SoftwareID		int = NULL,
	@Version		nvarchar(32) = NULL,
	@MD5			varchar(32),
	@Size			int,
	@DateTime		datetime = NULL,
	@FileVersion		nvarchar(256) = NULL,
	@FileDescription	nvarchar(256) = NULL,
	@Language		nvarchar(256) = NULL,
	@CompanyName		nvarchar(256) = NULL,
	@SoftwareFilePathID	int = NULL,
	@SoftwareFileNameID	int = NULL
AS
	DECLARE	@ID	int

	SELECT	@ID = SoftwareFileID
	FROM	[dbo].[SoftwareFile]
	WHERE	ComputerID = @ComputerID
	  AND	(SoftwareID = @SoftwareID OR (SoftwareID IS NULL AND @SoftwareID IS NULL))
	  AND	(SoftwareFilePathID = @SoftwareFilePathID OR (SoftwareFilePathID IS NULL AND @SoftwareFilePathID IS NULL))
	  AND	(SoftwareFileNameID = @SoftwareFileNameID OR (SoftwareFileNameID IS NULL AND @SoftwareFileNameID IS NULL))

	IF @ID IS NULL
		EXEC @ID = SoftwareFileAdd @ComputerID,
			@SoftwareID,
			@Version,
			@MD5,
			@Size,
			@DateTime,
			@FileVersion,
			@FileDescription,
			@Language,
			@CompanyName,
			@SoftwareFilePathID,
			@SoftwareFileNameID

	RETURN @ID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[SoftwareFileSchema]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[SoftwareFileSchema]
GO
CREATE PROCEDURE [dbo].[SoftwareFileSchema]
AS
	SELECT
	'IF OBJECT_ID(''tempdb..#SoftwareFile'') IS NULL' + CAST(0x0A AS CHAR(1)) +
	'	CREATE TABLE #SoftwareFile (' + CAST(0x0A AS CHAR(1)) +
	'		SoftwareFileID		int NULL,' + CAST(0x0A AS CHAR(1)) +
	'		ComputerID		int NOT NULL,' + CAST(0x0A AS CHAR(1)) +
	'		SoftwareID		int NULL,' + CAST(0x0A AS CHAR(1)) +
	'		Version			nvarchar(32) COLLATE database_default NULL,' + CAST(0x0A AS CHAR(1)) +
	'		MD5			varchar(32) COLLATE database_default NOT NULL,' + CAST(0x0A AS CHAR(1)) +
	'		[Size]			int NOT NULL,' + CAST(0x0A AS CHAR(1)) +
	'		[DateTime]		datetime NULL,' + CAST(0x0A AS CHAR(1)) +
	'		FileVersion		nvarchar(256) COLLATE database_default NULL,' + CAST(0x0A AS CHAR(1)) +
	'		FileDescription		nvarchar(256) COLLATE database_default NULL,' + CAST(0x0A AS CHAR(1)) +
	'		Language		nvarchar(256) COLLATE database_default NULL,' + CAST(0x0A AS CHAR(1)) +
	'		CompanyName		nvarchar(256) COLLATE database_default NULL,' + CAST(0x0A AS CHAR(1)) +
	'		SoftwareFilePathID	int NULL,' + CAST(0x0A AS CHAR(1)) +
	'		SoftwareFileNameID	int NULL' + CAST(0x0A AS CHAR(1)) +
	'	)' + CAST(0x0A AS CHAR(1)) +
	'ELSE' + CAST(0x0A AS CHAR(1)) +
	'	DELETE FROM #SoftwareFile' + CAST(0x0A AS CHAR(1)) +
	'' AS SQL
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[SoftwareFileTempAdd]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[SoftwareFileTempAdd]
GO
CREATE PROCEDURE dbo.[SoftwareFileTempAdd]
	@SoftwareFileID		int,
	@ComputerID		int,
	@SoftwareID		int = NULL,
	@Version		nvarchar(32) = NULL,
	@MD5			varchar(32),
	@Size			int,
	@DateTime		datetime = NULL,
	@FileVersion		nvarchar(256) = NULL,
	@FileDescription	nvarchar(256) = NULL,
	@Language		nvarchar(256) = NULL,
	@CompanyName		nvarchar(256) = NULL,
	@SoftwareFilePathID	int = NULL,
	@SoftwareFileNameID	int = NULL
AS
	INSERT INTO #SoftwareFile (
		SoftwareFileID,
		ComputerID,
		SoftwareID,
		Version,
		MD5,
		[Size],
		[DateTime],
		FileVersion,
		FileDescription,
		Language,
		CompanyName,
		SoftwareFilePathID,
		SoftwareFileNameID
	)
	VALUES (
		@SoftwareFileID,
		@ComputerID,
		@SoftwareID,
		@Version,
		@MD5,
		@Size,
		@DateTime,
		@FileVersion,
		@FileDescription,
		@Language,
		@CompanyName,
		@SoftwareFilePathID,
		@SoftwareFileNameID
	)
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[SoftwareFileAddBatch]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[SoftwareFileAddBatch]
GO
CREATE PROCEDURE dbo.[SoftwareFileAddBatch]
AS
	DECLARE @count int
	INSERT dbo.SoftwareFile (
		ComputerID,
		SoftwareID,
		Version,
		MD5,
		[Size],
		[DateTime],
		FileVersion,
		FileDescription,
		Language,
		CompanyName,
		SoftwareFilePathID,
		SoftwareFileNameID
	)
		SELECT	ComputerID,
			SoftwareID,
			Version,
			MD5,
			[Size],
			[DateTime],
			FileVersion,
			FileDescription,
			Language,
			CompanyName,
			SoftwareFilePathID,
			SoftwareFileNameID
		FROM #SoftwareFile
	SET @count = @@ROWCOUNT
	DROP TABLE #SoftwareFile	-- Drop temporary table
	RETURN @count
GO

/*
Add new SoftwareFile bound to
	SoftwareVersion using SoftwareName, Version
	SoftwareFilePath using Path
	SoftwareFileName using Name
	with ComputerID, Version, MD5, Size, DateTime, FileVersion, FileDescription, Language, CompanyName
*/

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[SoftwareFileUpdateByID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[SoftwareFileUpdateByID]
GO
CREATE PROCEDURE [dbo].[SoftwareFileUpdateByID]
	@SoftwareFileID		int,
	@ComputerID		int,
	@SoftwareID		int = NULL,
	@Version		nvarchar(32) = NULL,
	@MD5			varchar(32),
	@Size			int,
	@DateTime		datetime = NULL,
	@FileVersion		nvarchar(256) = NULL,
	@FileDescription	nvarchar(256) = NULL,
	@Language		nvarchar(256) = NULL,
	@CompanyName		nvarchar(256) = NULL,
	@SoftwareFilePathID	int = NULL,
	@SoftwareFileNameID	int = NULL
AS
	DECLARE	@ID	int
	SET @ID = 0

	UPDATE	[dbo].[SoftwareFile]
	SET	@ID = SoftwareFileID,
		ComputerID = @ComputerID,
		SoftwareID = @SoftwareID,
		Version = @Version,
		MD5 = @MD5,
		[Size] = @Size,
		[DateTime] = @DateTime,
		FileVersion = @FileVersion,
		FileDescription = @FileDescription,
		Language = @Language,
		CompanyName = @CompanyName,
		SoftwareFilePathID = @SoftwareFilePathID,
		SoftwareFileNameID = @SoftwareFileNameID
	WHERE	SoftwareFileID = @SoftwareFileID
	RETURN @ID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[SoftwareFileUpdateBatchByID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[SoftwareFileUpdateBatchByID]
GO
CREATE PROCEDURE dbo.[SoftwareFileUpdateBatchByID]
AS
	DECLARE @count int

	CREATE INDEX [TempSoftwareFileID]
		ON #SoftwareFile (SoftwareFileID)

	UPDATE	[dbo].[SoftwareFile]
	SET	ComputerID = t.ComputerID,
		SoftwareID = t.SoftwareID,
		Version = t.Version,
		MD5 = t.MD5,
		[Size] = t.[Size],
		[DateTime] = t.[DateTime],
		FileVersion = t.FileVersion,
		FileDescription = t.FileDescription,
		Language = t.Language,
		CompanyName = t.CompanyName,
		SoftwareFilePathID = t.SoftwareFilePathID,
		SoftwareFileNameID = t.SoftwareFileNameID
	FROM	#SoftwareFile AS t
	WHERE	SoftwareFile.SoftwareFileID = t.SoftwareFileID
	SET @count = @@ROWCOUNT
	DROP TABLE #SoftwareFile	-- Drop the temporary table
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[SoftwareFileUpdateByComputerIDSoftwareIDPathIDNameID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[SoftwareFileUpdateByComputerIDSoftwareIDPathIDNameID]
GO
CREATE PROCEDURE [dbo].[SoftwareFileUpdateByComputerIDSoftwareIDPathIDNameID]
	@ComputerID		int,
	@SoftwareID		int = NULL,
	@SoftwareFilePathID	int = NULL,
	@SoftwareFileNameID	int = NULL,
	@Version		nvarchar(32) = NULL,
	@MD5			varchar(32),
	@Size			int,
	@DateTime		datetime = NULL,
	@FileVersion		nvarchar(256) = NULL,
	@FileDescription	nvarchar(256) = NULL,
	@Language		nvarchar(256) = NULL,
	@CompanyName		nvarchar(256) = NULL
AS
	DECLARE	@ID	int
	SET @ID = 0

	UPDATE	[dbo].[SoftwareFile]
	SET	@ID = SoftwareFileID,
		Version = @Version,
		MD5 = @MD5,
		[Size] = @Size,
		[DateTime] = @DateTime,
		FileVersion = @FileVersion,
		FileDescription = @FileDescription,
		Language = @Language,
		CompanyName = @CompanyName
	WHERE	ComputerID = @ComputerID
	  AND	(SoftwareID = @SoftwareID OR (SoftwareID IS NULL AND @SoftwareID IS NULL))
	  AND	(SoftwareFilePathID = @SoftwareFilePathID OR (SoftwareFilePathID IS NULL AND @SoftwareFilePathID IS NULL))
	  AND	(SoftwareFileNameID = @SoftwareFileNameID OR (SoftwareFileNameID IS NULL AND @SoftwareFileNameID IS NULL))
	RETURN @ID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[SoftwareFileUpdateBatchByComputerIDSoftwareIDPathIDNameID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[SoftwareFileUpdateBatchByComputerIDSoftwareIDPathIDNameID]
GO
CREATE PROCEDURE dbo.[SoftwareFileUpdateBatchByComputerIDSoftwareIDPathIDNameID]
AS
	DECLARE @count int

	CREATE INDEX [TempSoftwareFileComputerIDSoftwareIDPathIDNameID]
		ON #SoftwareFile (ComputerID, SoftwareID, SoftwareFilePathID, SoftwareFileNameID)

	UPDATE	[dbo].[SoftwareFile]
	SET	Version = t.Version,
		MD5 = t.MD5,
		[Size] = t.[Size],
		[DateTime] = t.[DateTime],
		FileVersion = t.FileVersion,
		FileDescription = t.FileDescription,
		Language = t.Language,
		CompanyName = t.CompanyName
	FROM	#SoftwareFile AS t
	WHERE	SoftwareFile.ComputerID = t.ComputerID
	  AND	(SoftwareFile.SoftwareID = t.SoftwareID OR (SoftwareFile.SoftwareID IS NULL AND t.SoftwareID IS NULL))
	  AND	(SoftwareFile.SoftwareFilePathID = t.SoftwareFilePathID OR (SoftwareFile.SoftwareFilePathID IS NULL AND t.SoftwareFilePathID IS NULL))
	  AND	(SoftwareFile.SoftwareFileNameID = t.SoftwareFileNameID OR (SoftwareFile.SoftwareFileNameID IS NULL AND t.SoftwareFileNameID IS NULL))
	SET @count = @@ROWCOUNT
	DROP TABLE #SoftwareFile	-- Drop the temporary table
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[SoftwareFilePutByComputerIDSoftwareIDPathIDNameID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[SoftwareFilePutByComputerIDSoftwareIDPathIDNameID]
GO
CREATE PROCEDURE [dbo].[SoftwareFilePutByComputerIDSoftwareIDPathIDNameID]
	@ComputerID		int,
	@SoftwareID		int = NULL,
	@SoftwareFilePathID	int = NULL,
	@SoftwareFileNameID	int = NULL,
	@Version		nvarchar(32) = NULL,
	@MD5			varchar(32),
	@Size			int,
	@DateTime		datetime = NULL,
	@FileVersion		nvarchar(256) = NULL,
	@FileDescription	nvarchar(256) = NULL,
	@Language		nvarchar(256) = NULL,
	@CompanyName		nvarchar(256) = NULL
AS
	DECLARE @ID	int

	SELECT	@ID = SoftwareFileID
	FROM	SoftwareFile
	WHERE	ComputerID = @ComputerID
	  AND	(SoftwareID = @SoftwareID OR (SoftwareID IS NULL AND @SoftwareID IS NULL))
	  AND	(SoftwareFilePathID = @SoftwareFilePathID OR (SoftwareFilePathID IS NULL AND @SoftwareFilePathID IS NULL))
	  AND	(SoftwareFileNameID = @SoftwareFileNameID OR (SoftwareFileNameID IS NULL AND @SoftwareFileNameID IS NULL))

	IF @ID IS NULL
		EXEC @ID = SoftwareFileAdd @ComputerID,
			@SoftwareID,
			@Version,
			@MD5,
			@Size,
			@DateTime,
			@FileVersion,
			@FileDescription,
			@Language,
			@CompanyName,
			@SoftwareFilePathID,
			@SoftwareFileNameID
	ELSE
		EXEC SoftwareFileUpdateByComputerIDSoftwareIDPathIDNameID @ComputerID,
			@SoftwareID,
			@SoftwareFilePathID,
			@SoftwareFileNameID,
			@Version,
			@MD5,
			@Size,
			@DateTime,
			@FileVersion,
			@FileDescription,
			@Language,
			@CompanyName

	RETURN @ID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[SoftwareFilePutBatchByComputerIDSoftwareIDPathIDNameID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[SoftwareFilePutBatchByComputerIDSoftwareIDPathIDNameID]
GO
CREATE PROCEDURE [dbo].[SoftwareFilePutBatchByComputerIDSoftwareIDPathIDNameID]
AS
	DECLARE @count AS int
	SET @count = 0

	CREATE INDEX [TempSoftwareFileComputerIDSoftwareIDPathIDNameID]
		ON #SoftwareFile (ComputerID, SoftwareID, SoftwareFilePathID, SoftwareFileNameID)

	BEGIN TRANSACTION
	UPDATE [dbo].[SoftwareFile]
		SET	Version = t.Version,
			MD5 = t.MD5,
			[Size] = t.[Size],
			[DateTime] = t.[DateTime],
			FileVersion = t.FileVersion,
			FileDescription = t.FileDescription,
			Language = t.Language,
			CompanyName = t.CompanyName
		FROM	#SoftwareFile AS t
		WHERE	SoftwareFile.ComputerID = t.ComputerID
		  AND	(SoftwareFile.SoftwareID = t.SoftwareID OR (SoftwareFile.SoftwareID IS NULL AND t.SoftwareID IS NULL))
		  AND	(SoftwareFile.SoftwareFilePathID = t.SoftwareFilePathID OR (SoftwareFile.SoftwareFilePathID IS NULL AND t.SoftwareFilePathID IS NULL))
		  AND	(SoftwareFile.SoftwareFileNameID = t.SoftwareFileNameID OR (SoftwareFile.SoftwareFileNameID IS NULL AND t.SoftwareFileNameID IS NULL))
	SET @count = @@ROWCOUNT

	INSERT [dbo].[SoftwareFile] (
		ComputerID,
		SoftwareID,
		Version,
		MD5,
		[Size],
		[DateTime],
		FileVersion,
		FileDescription,
		Language,
		CompanyName,
		SoftwareFilePathID,
		SoftwareFileNameID
	)
		SELECT	ComputerID,
			SoftwareID,
			Version,
			MD5,
			[Size],
			[DateTime],
			FileVersion,
			FileDescription,
			Language,
			CompanyName,
			SoftwareFilePathID,
			SoftwareFileNameID
		FROM	#SoftwareFile AS t
		WHERE NOT EXISTS(	-- Current record doesn't exist
			SELECT * FROM [dbo].[SoftwareFile]
			WHERE	SoftwareFile.ComputerID = t.ComputerID
			  AND	(SoftwareFile.SoftwareID = t.SoftwareID OR (SoftwareFile.SoftwareID IS NULL AND t.SoftwareID IS NULL))
			  AND	(SoftwareFile.SoftwareFilePathID = t.SoftwareFilePathID OR (SoftwareFile.SoftwareFilePathID IS NULL AND t.SoftwareFilePathID IS NULL))
			  AND	(SoftwareFile.SoftwareFileNameID = t.SoftwareFileNameID OR (SoftwareFile.SoftwareFileNameID IS NULL AND t.SoftwareFileNameID IS NULL))
		)
	SET @count = @count + @@ROWCOUNT
	DROP TABLE #SoftwareFile	-- Drop the temporary table
	COMMIT WORK
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[SoftwareFileRemoveBatch]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[SoftwareFileRemoveBatch]
GO

CREATE PROCEDURE [dbo].[SoftwareFileRemoveBatch]
AS

	CREATE INDEX [TempSoftwareFileSoftwareFileRemoveBatch]
		ON #SoftwareFile (SoftwareFileID)	

	-- Delete records from SoftwareFile identified by fields of [TempSoftwareFileSoftwareFileRemoveBatch]
	DELETE [dbo].[SoftwareFile]
	WHERE EXISTS(
			SELECT * FROM #SoftwareFile AS t
			WHERE	SoftwareFile.SoftwareFileID = t.SoftwareFileID
		)
	DROP TABLE #SoftwareFile      -- Drop the temporary table
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[SoftwareFileRemoveByID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[SoftwareFileRemoveByID]
GO
CREATE PROCEDURE [dbo].[SoftwareFileRemoveByID]
	@SoftwareFileID		int
AS
	-- SoftwareFile deletes cascade to:
	--	SoftwareFileProperty by FK_SoftwareFileProperty_SoftwareFile
	DELETE	[dbo].[SoftwareFile]
	WHERE	SoftwareFileID = @SoftwareFileID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[SoftwareFileRemoveAllByComputerID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[SoftwareFileRemoveAllByComputerID]
GO
CREATE PROCEDURE [dbo].[SoftwareFileRemoveAllByComputerID]
	@ComputerID		int
AS
	DELETE	[dbo].[SoftwareFile]
	WHERE	ComputerID = @ComputerID
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[SoftwareFileRemoveAll]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[SoftwareFileRemoveAll]
GO
CREATE PROCEDURE [dbo].[SoftwareFileRemoveAll]
	
AS
	DELETE	[dbo].[SoftwareFile]
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[SoftwareFileReplaceSubsetByComputerID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[SoftwareFileReplaceSubsetByComputerID]
GO
-- Replace the record subset selected by (@ComputerID)
-- using unique identifier (ComputerID, SoftwareID, SoftwareFilePathID, SoftwareFileNameID)
-- updating fields (Version, MD5, [Size], [DateTime], FileVersion, FileDescription, Language, CompanyName)
CREATE PROCEDURE [dbo].[SoftwareFileReplaceSubsetByComputerID]
	@ComputerID		int
AS
	DECLARE @count AS int
	SET @count = 0

	CREATE INDEX [TempSoftwareFileByComputerID]
		ON #SoftwareFile (ComputerID, SoftwareID, SoftwareFilePathID, SoftwareFileNameID)

	BEGIN TRANSACTION
	DELETE [SoftwareFile]
		WHERE	ComputerID = @ComputerID
		AND NOT EXISTS(		-- Replacement record doesn't exist
			SELECT * FROM #SoftwareFile AS t
			WHERE	SoftwareFile.ComputerID = t.ComputerID
			  AND	(SoftwareFile.SoftwareID = t.SoftwareID OR (SoftwareFile.SoftwareID IS NULL AND t.SoftwareID IS NULL))
			  AND	(SoftwareFile.SoftwareFilePathID = t.SoftwareFilePathID OR (SoftwareFile.SoftwareFilePathID IS NULL AND t.SoftwareFilePathID IS NULL))
			  AND	(SoftwareFile.SoftwareFileNameID = t.SoftwareFileNameID OR (SoftwareFile.SoftwareFileNameID IS NULL AND t.SoftwareFileNameID IS NULL))
		)

	UPDATE [dbo].[SoftwareFile]
		SET	Version = t.Version,
			MD5 = t.MD5,
			[Size] = t.[Size],
			[DateTime] = t.[DateTime],
			FileVersion = t.FileVersion,
			FileDescription = t.FileDescription,
			Language = t.Language,
			CompanyName = t.CompanyName
		FROM	#SoftwareFile AS t
		WHERE	SoftwareFile.ComputerID = t.ComputerID
		  AND	(SoftwareFile.SoftwareID = t.SoftwareID OR (SoftwareFile.SoftwareID IS NULL AND t.SoftwareID IS NULL))
		  AND	(SoftwareFile.SoftwareFilePathID = t.SoftwareFilePathID OR (SoftwareFile.SoftwareFilePathID IS NULL AND t.SoftwareFilePathID IS NULL))
		  AND	(SoftwareFile.SoftwareFileNameID = t.SoftwareFileNameID OR (SoftwareFile.SoftwareFileNameID IS NULL AND t.SoftwareFileNameID IS NULL))
	SET @count = @@ROWCOUNT

	INSERT [SoftwareFile] (
		ComputerID,
		SoftwareID,
		Version,
		MD5,
		[Size],
		[DateTime],
		FileVersion,
		FileDescription,
		Language,
		CompanyName,
		SoftwareFilePathID,
		SoftwareFileNameID
	)
		SELECT	ComputerID,
			SoftwareID,
			Version,
			MD5,
			[Size],
			[DateTime],
			FileVersion,
			FileDescription,
			Language,
			CompanyName,
			SoftwareFilePathID,
			SoftwareFileNameID
		FROM	#SoftwareFile AS t
		WHERE NOT EXISTS(	-- Current record doesn't exist
			SELECT * FROM [SoftwareFile]
			WHERE	SoftwareFile.ComputerID = t.ComputerID
			  AND	(SoftwareFile.SoftwareID = t.SoftwareID OR (SoftwareFile.SoftwareID IS NULL AND t.SoftwareID IS NULL))
			  AND	(SoftwareFile.SoftwareFilePathID = t.SoftwareFilePathID OR (SoftwareFile.SoftwareFilePathID IS NULL AND t.SoftwareFilePathID IS NULL))
			  AND	(SoftwareFile.SoftwareFileNameID = t.SoftwareFileNameID OR (SoftwareFile.SoftwareFileNameID IS NULL AND t.SoftwareFileNameID IS NULL))
		)
	SET @count = @count + @@ROWCOUNT
	DROP TABLE #SoftwareFile	-- Drop the temporary table
	COMMIT WORK
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[SoftwareFilePropertyGetBySoftwareFileIDName]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[SoftwareFilePropertyGetBySoftwareFileIDName]
GO
CREATE PROCEDURE [dbo].[SoftwareFilePropertyGetBySoftwareFileIDName]
	@SoftwareFileID		int,
	@Name			nvarchar(256)
AS
	SELECT	SoftwareFileID,
		[Name],
		Value
	FROM	[dbo].[SoftwareFileProperty]
	WHERE	SoftwareFileID = @SoftwareFileID
	  AND	[Name] = @Name
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[SoftwareFilePropertyGetAllBySoftwareFileID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[SoftwareFilePropertyGetAllBySoftwareFileID]
GO
CREATE PROCEDURE [dbo].[SoftwareFilePropertyGetAllBySoftwareFileID]
	@SoftwareFileID		int
AS
	SELECT	SoftwareFileID,
		[Name],
		Value
	FROM	[dbo].[SoftwareFileProperty]
	WHERE	SoftwareFileID = @SoftwareFileID
	ORDER BY [Name]
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[SoftwareFilePropertyGetAll]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[SoftwareFilePropertyGetAll]
GO
CREATE PROCEDURE [dbo].[SoftwareFilePropertyGetAll]
AS
	SELECT	SoftwareFileID,
		[Name],
		Value
	FROM	[dbo].[SoftwareFileProperty]
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[SoftwareFilePropertyAdd]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[SoftwareFilePropertyAdd]
GO
CREATE PROCEDURE [dbo].[SoftwareFilePropertyAdd]
	@SoftwareFileID		int,
	@Name			nvarchar(256),
	@Value			nvarchar(256)
AS
	INSERT INTO  dbo.SoftwareFileProperty (
		SoftwareFileID,
		[Name],
		Value
	)
	VALUES (
		@SoftwareFileID,
		@Name,
		@Value
	)
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[SoftwareFilePropertySchema]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[SoftwareFilePropertySchema]
GO
CREATE PROCEDURE [dbo].[SoftwareFilePropertySchema]
AS
	SELECT
	'IF OBJECT_ID(''tempdb..#SoftwareFileProperty'') IS NULL' + CAST(0x0A AS CHAR(1)) +
	'	CREATE TABLE #SoftwareFileProperty (' + CAST(0x0A AS CHAR(1)) +
	'		SoftwareFileID		int NOT NULL,' + CAST(0x0A AS CHAR(1)) +
	'		[Name]			nvarchar(256) COLLATE database_default NOT NULL,' + CAST(0x0A AS CHAR(1)) +
	'		Value			nvarchar(256) COLLATE database_default NOT NULL' + CAST(0x0A AS CHAR(1)) +
	'	)' + CAST(0x0A AS CHAR(1)) +
	'ELSE' + CAST(0x0A AS CHAR(1)) +
	'	DELETE FROM #SoftwareFileProperty' + CAST(0x0A AS CHAR(1)) +
	'' AS SQL
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[SoftwareFilePropertyTempAdd]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[SoftwareFilePropertyTempAdd]
GO
CREATE PROCEDURE dbo.[SoftwareFilePropertyTempAdd]
	@SoftwareFileID		int,
	@Name			nvarchar(256),
	@Value			nvarchar(256)
AS
	INSERT INTO #SoftwareFileProperty (
		SoftwareFileID,
		[Name],
		Value
	)
	VALUES (
		@SoftwareFileID,
		@Name,
		@Value
	)
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[SoftwareFilePropertyAddBatch]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[SoftwareFilePropertyAddBatch]
GO
CREATE PROCEDURE dbo.[SoftwareFilePropertyAddBatch]
AS
	DECLARE @count int
	INSERT dbo.SoftwareFileProperty (
		SoftwareFileID,
		[Name],
		Value
	)
		SELECT	SoftwareFileID,
			[Name],
			Value
		FROM #SoftwareFileProperty
	SET @count = @@ROWCOUNT
	DROP TABLE #SoftwareFileProperty	-- Drop temporary table
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[SoftwareFilePropertyUpdateBySoftwareFileIDName]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[SoftwareFilePropertyUpdateBySoftwareFileIDName]
GO
CREATE PROCEDURE [dbo].[SoftwareFilePropertyUpdateBySoftwareFileIDName]
	@SoftwareFileID		int,
	@Name			nvarchar(256),
	@Value			nvarchar(256)
AS
	UPDATE	[dbo].[SoftwareFileProperty]
	SET	Value = @Value
	WHERE	SoftwareFileID = @SoftwareFileID
	  AND	[Name] = @Name
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[SoftwareFilePropertyUpdateBatchBySoftwareFileIDName]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[SoftwareFilePropertyUpdateBatchBySoftwareFileIDName]
GO
CREATE PROCEDURE dbo.[SoftwareFilePropertyUpdateBatchBySoftwareFileIDName]
AS
	DECLARE @count int

	CREATE INDEX [TempSoftwareFilePropertySoftwareFileIDName]
		ON #SoftwareFileProperty (SoftwareFileID, [Name])

	UPDATE	[dbo].[SoftwareFileProperty]
	SET	Value = t.Value
	FROM	#SoftwareFileProperty AS t
	WHERE	SoftwareFileProperty.SoftwareFileID = t.SoftwareFileID
	  AND	SoftwareFileProperty.[Name] = t.[Name]
	SET @count = @@ROWCOUNT
	DROP TABLE #SoftwareFileProperty	-- Drop the temporary table
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[SoftwareFilePropertyPutBySoftwareFileIDName]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[SoftwareFilePropertyPutBySoftwareFileIDName]
GO
CREATE PROCEDURE [dbo].[SoftwareFilePropertyPutBySoftwareFileIDName]
	@SoftwareFileID		int,
	@Name			nvarchar(256),
	@Value			nvarchar(256)
AS
	IF NOT EXISTS(
		SELECT	1
		FROM	dbo.SoftwareFileProperty
		WHERE	SoftwareFileID = @SoftwareFileID
		  AND	[Name] = @Name
	)
		EXEC SoftwareFilePropertyAdd @SoftwareFileID,
			@Name,
			@Value
	ELSE
		EXEC SoftwareFilePropertyUpdateBySoftwareFileIDName @SoftwareFileID,
			@Name,
			@Value
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[SoftwareFilePropertyPutBatchBySoftwareFileIDName]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[SoftwareFilePropertyPutBatchBySoftwareFileIDName]
GO
CREATE PROCEDURE [dbo].[SoftwareFilePropertyPutBatchBySoftwareFileIDName]
AS
	DECLARE @count AS int
	SET @count = 0

	CREATE INDEX [TempSoftwareFilePropertySoftwareFileIDName]
		ON #SoftwareFileProperty (SoftwareFileID, [Name])

	BEGIN TRANSACTION
	UPDATE [dbo].[SoftwareFileProperty]
		SET	Value = t.Value
		FROM	#SoftwareFileProperty AS t
		WHERE	SoftwareFileProperty.SoftwareFileID = t.SoftwareFileID
		  AND	SoftwareFileProperty.[Name] = t.[Name]
	SET @count = @@ROWCOUNT

	INSERT [dbo].[SoftwareFileProperty] (
		SoftwareFileID,
		[Name],
		Value
	)
		SELECT	SoftwareFileID,
			[Name],
			Value
		FROM	#SoftwareFileProperty AS t
		WHERE NOT EXISTS(	-- Current record doesn't exist
			SELECT * FROM [dbo].[SoftwareFileProperty]
			WHERE	SoftwareFileProperty.SoftwareFileID = t.SoftwareFileID
			  AND	SoftwareFileProperty.[Name] = t.[Name]
		)
	SET @count = @count + @@ROWCOUNT
	DROP TABLE #SoftwareFileProperty	-- Drop the temporary table
	COMMIT WORK
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[SoftwareFilePropertyRemoveBatch]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[SoftwareFilePropertyRemoveBatch]
GO

CREATE PROCEDURE [dbo].[SoftwareFilePropertyRemoveBatch]
AS

	CREATE INDEX [TempSoftwareFilePropertySoftwareFilePropertyRemoveBatch]
		ON #SoftwareFileProperty (SoftwareFileID, [Name])	

	-- Delete records from SoftwareFileProperty identified by fields of [TempSoftwareFilePropertySoftwareFilePropertyRemoveBatch]
	DELETE [dbo].[SoftwareFileProperty]
	WHERE EXISTS(
			SELECT * FROM #SoftwareFileProperty AS t
			WHERE	SoftwareFileProperty.SoftwareFileID = t.SoftwareFileID
			  AND	SoftwareFileProperty.[Name] = t.[Name]
		)
	DROP TABLE #SoftwareFileProperty      -- Drop the temporary table
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[SoftwareFilePropertyRemoveBySoftwareFileIDName]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[SoftwareFilePropertyRemoveBySoftwareFileIDName]
GO
CREATE PROCEDURE [dbo].[SoftwareFilePropertyRemoveBySoftwareFileIDName]
	@SoftwareFileID		int,
	@Name			nvarchar(256)
AS
	DELETE	[dbo].[SoftwareFileProperty]
	WHERE	SoftwareFileID = @SoftwareFileID
	  AND	[Name] = @Name
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[SoftwareFilePropertyRemoveAllBySoftwareFileID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[SoftwareFilePropertyRemoveAllBySoftwareFileID]
GO
CREATE PROCEDURE [dbo].[SoftwareFilePropertyRemoveAllBySoftwareFileID]
	@SoftwareFileID		int
AS
	DELETE	[dbo].[SoftwareFileProperty]
	WHERE	SoftwareFileID = @SoftwareFileID
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[SoftwareFilePropertyRemoveAll]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[SoftwareFilePropertyRemoveAll]
GO
CREATE PROCEDURE [dbo].[SoftwareFilePropertyRemoveAll]
	
AS
	DELETE	[dbo].[SoftwareFileProperty]
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[SoftwareFilePropertyReplaceSubsetBySoftwareFileID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[SoftwareFilePropertyReplaceSubsetBySoftwareFileID]
GO
-- Replace the record subset selected by (@SoftwareFileID)
-- using unique identifier (SoftwareFileID, [Name])
-- updating fields (Value)
CREATE PROCEDURE [dbo].[SoftwareFilePropertyReplaceSubsetBySoftwareFileID]
	@SoftwareFileID		int
AS
	DECLARE @count AS int
	SET @count = 0

	CREATE INDEX [TempSoftwareFilePropertyBySoftwareFileID]
		ON #SoftwareFileProperty (SoftwareFileID, [Name])

	BEGIN TRANSACTION
	DELETE [SoftwareFileProperty]
		WHERE	SoftwareFileID = @SoftwareFileID
		AND NOT EXISTS(		-- Replacement record doesn't exist
			SELECT * FROM #SoftwareFileProperty AS t
			WHERE	SoftwareFileProperty.SoftwareFileID = t.SoftwareFileID
			  AND	SoftwareFileProperty.[Name] = t.[Name]
		)

	UPDATE [dbo].[SoftwareFileProperty]
		SET	Value = t.Value
		FROM	#SoftwareFileProperty AS t
		WHERE	SoftwareFileProperty.SoftwareFileID = t.SoftwareFileID
		  AND	SoftwareFileProperty.[Name] = t.[Name]
	SET @count = @@ROWCOUNT

	INSERT [SoftwareFileProperty] (
		SoftwareFileID,
		[Name],
		Value
	)
		SELECT	SoftwareFileID,
			[Name],
			Value
		FROM	#SoftwareFileProperty AS t
		WHERE NOT EXISTS(	-- Current record doesn't exist
			SELECT * FROM [SoftwareFileProperty]
			WHERE	SoftwareFileProperty.SoftwareFileID = t.SoftwareFileID
			  AND	SoftwareFileProperty.[Name] = t.[Name]
		)
	SET @count = @count + @@ROWCOUNT
	DROP TABLE #SoftwareFileProperty	-- Drop the temporary table
	COMMIT WORK
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[HardwareClassGetByID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[HardwareClassGetByID]
GO
CREATE PROCEDURE [dbo].[HardwareClassGetByID]
	@HardwareClassID	int
AS
	SELECT	HardwareClassID,
		Class,
		SuperClassID
	FROM	[dbo].[HardwareClass]
	WHERE	HardwareClassID = @HardwareClassID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[HardwareClassGetByClass]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[HardwareClassGetByClass]
GO
CREATE PROCEDURE [dbo].[HardwareClassGetByClass]
	@Class			nvarchar(256)
AS
	SELECT	HardwareClassID,
		Class,
		SuperClassID
	FROM	[dbo].[HardwareClass]
	WHERE	Class = @Class
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[HardwareClassGetAll]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[HardwareClassGetAll]
GO
CREATE PROCEDURE [dbo].[HardwareClassGetAll]
AS
	SELECT	HardwareClassID,
		Class,
		SuperClassID
	FROM	[dbo].[HardwareClass]
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[HardwareClassAdd]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[HardwareClassAdd]
GO
CREATE PROCEDURE [dbo].[HardwareClassAdd]
	@Class			nvarchar(256),
	@SuperClassID		int = NULL
AS
	INSERT INTO  dbo.HardwareClass (
		Class,
		SuperClassID
	)
	VALUES (
		@Class,
		@SuperClassID
	)
	RETURN SCOPE_IDENTITY()
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[HardwareClassBind]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[HardwareClassBind]
GO
CREATE PROCEDURE [dbo].[HardwareClassBind]
	@Class			nvarchar(256),
	@SuperClassID		int = NULL
AS
	DECLARE	@ID	int

	SELECT	@ID = HardwareClassID
	FROM	[dbo].[HardwareClass]
	WHERE	Class = @Class

	IF @ID IS NULL
		EXEC @ID = HardwareClassAdd @Class,
			@SuperClassID

	RETURN @ID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[HardwareClassSchema]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[HardwareClassSchema]
GO
CREATE PROCEDURE [dbo].[HardwareClassSchema]
AS
	SELECT
	'IF OBJECT_ID(''tempdb..#HardwareClass'') IS NULL' + CAST(0x0A AS CHAR(1)) +
	'	CREATE TABLE #HardwareClass (' + CAST(0x0A AS CHAR(1)) +
	'		HardwareClassID		int NULL,' + CAST(0x0A AS CHAR(1)) +
	'		Class			nvarchar(256) COLLATE database_default NOT NULL,' + CAST(0x0A AS CHAR(1)) +
	'		SuperClassID		int NULL' + CAST(0x0A AS CHAR(1)) +
	'	)' + CAST(0x0A AS CHAR(1)) +
	'ELSE' + CAST(0x0A AS CHAR(1)) +
	'	DELETE FROM #HardwareClass' + CAST(0x0A AS CHAR(1)) +
	'' AS SQL
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[HardwareClassTempAdd]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[HardwareClassTempAdd]
GO
CREATE PROCEDURE dbo.[HardwareClassTempAdd]
	@HardwareClassID	int,
	@Class			nvarchar(256),
	@SuperClassID		int = NULL
AS
	INSERT INTO #HardwareClass (
		HardwareClassID,
		Class,
		SuperClassID
	)
	VALUES (
		@HardwareClassID,
		@Class,
		@SuperClassID
	)
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[HardwareClassAddBatch]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[HardwareClassAddBatch]
GO
CREATE PROCEDURE dbo.[HardwareClassAddBatch]
AS
	DECLARE @count int
	INSERT dbo.HardwareClass (
		Class,
		SuperClassID
	)
		SELECT	Class,
			SuperClassID
		FROM #HardwareClass
	SET @count = @@ROWCOUNT
	DROP TABLE #HardwareClass	-- Drop temporary table
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[HardwareClassUpdateByID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[HardwareClassUpdateByID]
GO
CREATE PROCEDURE [dbo].[HardwareClassUpdateByID]
	@HardwareClassID	int,
	@Class			nvarchar(256),
	@SuperClassID		int = NULL
AS
	DECLARE	@ID	int
	SET @ID = 0

	UPDATE	[dbo].[HardwareClass]
	SET	@ID = HardwareClassID,
		Class = @Class,
		SuperClassID = @SuperClassID
	WHERE	HardwareClassID = @HardwareClassID
	RETURN @ID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[HardwareClassUpdateBatchByID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[HardwareClassUpdateBatchByID]
GO
CREATE PROCEDURE dbo.[HardwareClassUpdateBatchByID]
AS
	DECLARE @count int

	CREATE INDEX [TempHardwareClassID]
		ON #HardwareClass (HardwareClassID)

	UPDATE	[dbo].[HardwareClass]
	SET	Class = t.Class,
		SuperClassID = t.SuperClassID
	FROM	#HardwareClass AS t
	WHERE	HardwareClass.HardwareClassID = t.HardwareClassID
	SET @count = @@ROWCOUNT
	DROP TABLE #HardwareClass	-- Drop the temporary table
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[HardwareClassUpdateByClass]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[HardwareClassUpdateByClass]
GO
CREATE PROCEDURE [dbo].[HardwareClassUpdateByClass]
	@Class			nvarchar(256),
	@SuperClassID		int = NULL
AS
	DECLARE	@ID	int
	SET @ID = 0

	UPDATE	[dbo].[HardwareClass]
	SET	@ID = HardwareClassID,
		SuperClassID = @SuperClassID
	WHERE	Class = @Class
	RETURN @ID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[HardwareClassUpdateBatchByClass]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[HardwareClassUpdateBatchByClass]
GO
CREATE PROCEDURE dbo.[HardwareClassUpdateBatchByClass]
AS
	DECLARE @count int

	CREATE INDEX [TempHardwareClassClass]
		ON #HardwareClass (Class)

	UPDATE	[dbo].[HardwareClass]
	SET	SuperClassID = t.SuperClassID
	FROM	#HardwareClass AS t
	WHERE	HardwareClass.Class = t.Class
	SET @count = @@ROWCOUNT
	DROP TABLE #HardwareClass	-- Drop the temporary table
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[HardwareClassPutByClass]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[HardwareClassPutByClass]
GO
CREATE PROCEDURE [dbo].[HardwareClassPutByClass]
	@Class			nvarchar(256),
	@SuperClassID		int = NULL
AS
	DECLARE @ID	int

	SELECT	@ID = HardwareClassID
	FROM	HardwareClass
	WHERE	Class = @Class

	IF @ID IS NULL
		EXEC @ID = HardwareClassAdd @Class,
			@SuperClassID
	ELSE
		EXEC HardwareClassUpdateByClass @Class,
			@SuperClassID

	RETURN @ID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[HardwareClassPutBatchByClass]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[HardwareClassPutBatchByClass]
GO
CREATE PROCEDURE [dbo].[HardwareClassPutBatchByClass]
AS
	DECLARE @count AS int
	SET @count = 0

	CREATE INDEX [TempHardwareClassClass]
		ON #HardwareClass (Class)

	BEGIN TRANSACTION
	UPDATE [dbo].[HardwareClass]
		SET	SuperClassID = t.SuperClassID
		FROM	#HardwareClass AS t
		WHERE	HardwareClass.Class = t.Class
	SET @count = @@ROWCOUNT

	INSERT [dbo].[HardwareClass] (
		Class,
		SuperClassID
	)
		SELECT	Class,
			SuperClassID
		FROM	#HardwareClass AS t
		WHERE NOT EXISTS(	-- Current record doesn't exist
			SELECT * FROM [dbo].[HardwareClass]
			WHERE	HardwareClass.Class = t.Class
		)
	SET @count = @count + @@ROWCOUNT
	DROP TABLE #HardwareClass	-- Drop the temporary table
	COMMIT WORK
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[HardwareClassRemoveBatch]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[HardwareClassRemoveBatch]
GO

CREATE PROCEDURE [dbo].[HardwareClassRemoveBatch]
AS

	CREATE INDEX [TempHardwareClassHardwareClassRemoveBatch]
		ON #HardwareClass (HardwareClassID)	

	-- Delete records from HardwareClass identified by fields of [TempHardwareClassHardwareClassRemoveBatch]
	DELETE [dbo].[HardwareClass]
	WHERE EXISTS(
			SELECT * FROM #HardwareClass AS t
			WHERE	HardwareClass.HardwareClassID = t.HardwareClassID
		)
	DROP TABLE #HardwareClass      -- Drop the temporary table
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[HardwareClassRemoveByClass]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[HardwareClassRemoveByClass]
GO
CREATE PROCEDURE [dbo].[HardwareClassRemoveByClass]
	@Class			nvarchar(256)
AS
	-- HardwareClass deletes cascade to:
	--	HardwareObject by FK_HardwareObject_Class
	--		HardwareValue by FK_HardwareValue_HardwareObject
	-- HardwareClass deletes may fail due to non-cascading FKs:
	--	HardwareClass by FK_HardwareClass_Superclass
	DELETE	[dbo].[HardwareClass]
	WHERE	Class = @Class
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[HardwareClassRemoveAll]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[HardwareClassRemoveAll]
GO
CREATE PROCEDURE [dbo].[HardwareClassRemoveAll]
	
AS
	DELETE	[dbo].[HardwareClass]
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[HardwareObjectGetByComputerIDHardwareNameOccurrenceHardwareClassID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[HardwareObjectGetByComputerIDHardwareNameOccurrenceHardwareClassID]
GO
CREATE PROCEDURE [dbo].[HardwareObjectGetByComputerIDHardwareNameOccurrenceHardwareClassID]
	@ComputerID		int,
	@HardwareName		nvarchar(256),
	@Occurrence		int,
	@HardwareClassID	int
AS
	SELECT	HardwareObjectID,
		ComputerID,
		HardwareName,
		Occurrence,
		HardwareClassID
	FROM	[dbo].[HardwareObject]
	WHERE	ComputerID = @ComputerID
	  AND	HardwareName = @HardwareName
	  AND	Occurrence = @Occurrence
	  AND	HardwareClassID = @HardwareClassID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[HardwareObjectGetAllByComputerID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[HardwareObjectGetAllByComputerID]
GO
CREATE PROCEDURE [dbo].[HardwareObjectGetAllByComputerID]
	@ComputerID		int
AS
	SELECT	HardwareObjectID,
		ComputerID,
		HardwareName,
		Occurrence,
		HardwareClassID
	FROM	[dbo].[HardwareObject]
	WHERE	ComputerID = @ComputerID
	ORDER BY HardwareName, Occurrence, HardwareClassID
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[HardwareObjectGetByID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[HardwareObjectGetByID]
GO
CREATE PROCEDURE [dbo].[HardwareObjectGetByID]
	@HardwareObjectID	int
AS
	SELECT	HardwareObjectID,
		ComputerID,
		HardwareName,
		Occurrence,
		HardwareClassID
	FROM	[dbo].[HardwareObject]
	WHERE	HardwareObjectID = @HardwareObjectID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[HardwareObjectGetAll]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[HardwareObjectGetAll]
GO
CREATE PROCEDURE [dbo].[HardwareObjectGetAll]
AS
	SELECT	HardwareObjectID,
		ComputerID,
		HardwareName,
		Occurrence,
		HardwareClassID
	FROM	[dbo].[HardwareObject]
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[HardwareObjectAdd]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[HardwareObjectAdd]
GO
CREATE PROCEDURE [dbo].[HardwareObjectAdd]
	@ComputerID		int,
	@HardwareName		nvarchar(256),
	@Occurrence		int,
	@HardwareClassID	int
AS
	INSERT INTO  dbo.HardwareObject (
		ComputerID,
		HardwareName,
		Occurrence,
		HardwareClassID
	)
	VALUES (
		@ComputerID,
		@HardwareName,
		@Occurrence,
		@HardwareClassID
	)
	RETURN SCOPE_IDENTITY()
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[HardwareObjectBind]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[HardwareObjectBind]
GO
CREATE PROCEDURE [dbo].[HardwareObjectBind]
	@ComputerID		int,
	@HardwareName		nvarchar(256),
	@Occurrence		int,
	@HardwareClassID	int
AS
	DECLARE	@ID	int

	SELECT	@ID = HardwareObjectID
	FROM	[dbo].[HardwareObject]
	WHERE	ComputerID = @ComputerID
	  AND	HardwareName = @HardwareName
	  AND	Occurrence = @Occurrence
	  AND	HardwareClassID = @HardwareClassID

	IF @ID IS NULL
		EXEC @ID = HardwareObjectAdd @ComputerID,
			@HardwareName,
			@Occurrence,
			@HardwareClassID

	RETURN @ID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[HardwareObjectSchema]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[HardwareObjectSchema]
GO
CREATE PROCEDURE [dbo].[HardwareObjectSchema]
AS
	SELECT
	'IF OBJECT_ID(''tempdb..#HardwareObject'') IS NULL' + CAST(0x0A AS CHAR(1)) +
	'	CREATE TABLE #HardwareObject (' + CAST(0x0A AS CHAR(1)) +
	'		HardwareObjectID	int NULL,' + CAST(0x0A AS CHAR(1)) +
	'		ComputerID		int NOT NULL,' + CAST(0x0A AS CHAR(1)) +
	'		HardwareName		nvarchar(256) COLLATE database_default NOT NULL,' + CAST(0x0A AS CHAR(1)) +
	'		Occurrence		int NOT NULL,' + CAST(0x0A AS CHAR(1)) +
	'		HardwareClassID		int NOT NULL' + CAST(0x0A AS CHAR(1)) +
	'	)' + CAST(0x0A AS CHAR(1)) +
	'ELSE' + CAST(0x0A AS CHAR(1)) +
	'	DELETE FROM #HardwareObject' + CAST(0x0A AS CHAR(1)) +
	'' AS SQL
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[HardwareObjectTempAdd]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[HardwareObjectTempAdd]
GO
CREATE PROCEDURE dbo.[HardwareObjectTempAdd]
	@HardwareObjectID	int,
	@ComputerID		int,
	@HardwareName		nvarchar(256),
	@Occurrence		int,
	@HardwareClassID	int
AS
	INSERT INTO #HardwareObject (
		HardwareObjectID,
		ComputerID,
		HardwareName,
		Occurrence,
		HardwareClassID
	)
	VALUES (
		@HardwareObjectID,
		@ComputerID,
		@HardwareName,
		@Occurrence,
		@HardwareClassID
	)
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[HardwareObjectAddBatch]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[HardwareObjectAddBatch]
GO
CREATE PROCEDURE dbo.[HardwareObjectAddBatch]
AS
	DECLARE @count int
	INSERT dbo.HardwareObject (
		ComputerID,
		HardwareName,
		Occurrence,
		HardwareClassID
	)
		SELECT	ComputerID,
			HardwareName,
			Occurrence,
			HardwareClassID
		FROM #HardwareObject
	SET @count = @@ROWCOUNT
	DROP TABLE #HardwareObject	-- Drop temporary table
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[HardwareObjectUpdateByID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[HardwareObjectUpdateByID]
GO
CREATE PROCEDURE [dbo].[HardwareObjectUpdateByID]
	@HardwareObjectID	int,
	@ComputerID		int,
	@HardwareName		nvarchar(256),
	@Occurrence		int,
	@HardwareClassID	int
AS
	DECLARE	@ID	int
	SET @ID = 0

	UPDATE	[dbo].[HardwareObject]
	SET	@ID = HardwareObjectID,
		ComputerID = @ComputerID,
		HardwareName = @HardwareName,
		Occurrence = @Occurrence,
		HardwareClassID = @HardwareClassID
	WHERE	HardwareObjectID = @HardwareObjectID
	RETURN @ID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[HardwareObjectUpdateBatchByID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[HardwareObjectUpdateBatchByID]
GO
CREATE PROCEDURE dbo.[HardwareObjectUpdateBatchByID]
AS
	DECLARE @count int

	CREATE INDEX [TempHardwareObjectID]
		ON #HardwareObject (HardwareObjectID)

	UPDATE	[dbo].[HardwareObject]
	SET	ComputerID = t.ComputerID,
		HardwareName = t.HardwareName,
		Occurrence = t.Occurrence,
		HardwareClassID = t.HardwareClassID
	FROM	#HardwareObject AS t
	WHERE	HardwareObject.HardwareObjectID = t.HardwareObjectID
	SET @count = @@ROWCOUNT
	DROP TABLE #HardwareObject	-- Drop the temporary table
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[HardwareObjectPutByComputerIDHardwareNameOccurrenceHardwareClassID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[HardwareObjectPutByComputerIDHardwareNameOccurrenceHardwareClassID]
GO
CREATE PROCEDURE [dbo].[HardwareObjectPutByComputerIDHardwareNameOccurrenceHardwareClassID]
	@ComputerID		int,
	@HardwareName		nvarchar(256),
	@Occurrence		int,
	@HardwareClassID	int
AS
	DECLARE @ID	int

	SELECT	@ID = HardwareObjectID
	FROM	HardwareObject
	WHERE	ComputerID = @ComputerID
	  AND	HardwareName = @HardwareName
	  AND	Occurrence = @Occurrence
	  AND	HardwareClassID = @HardwareClassID

	IF @ID IS NULL
		EXEC @ID = HardwareObjectAdd @ComputerID,
			@HardwareName,
			@Occurrence,
			@HardwareClassID

	RETURN @ID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[HardwareObjectPutBatchByComputerIDHardwareNameOccurrenceHardwareClassID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[HardwareObjectPutBatchByComputerIDHardwareNameOccurrenceHardwareClassID]
GO
CREATE PROCEDURE [dbo].[HardwareObjectPutBatchByComputerIDHardwareNameOccurrenceHardwareClassID]
AS
	DECLARE @count AS int
	SET @count = 0

	CREATE INDEX [TempHardwareObjectComputerIDHardwareNameOccurrenceHardwareClassID]
		ON #HardwareObject (ComputerID, HardwareName, Occurrence, HardwareClassID)

	BEGIN TRANSACTION

	INSERT [dbo].[HardwareObject] (
		ComputerID,
		HardwareName,
		Occurrence,
		HardwareClassID
	)
		SELECT	ComputerID,
			HardwareName,
			Occurrence,
			HardwareClassID
		FROM	#HardwareObject AS t
		WHERE NOT EXISTS(	-- Current record doesn't exist
			SELECT * FROM [dbo].[HardwareObject]
			WHERE	HardwareObject.ComputerID = t.ComputerID
			  AND	HardwareObject.HardwareName = t.HardwareName
			  AND	HardwareObject.Occurrence = t.Occurrence
			  AND	HardwareObject.HardwareClassID = t.HardwareClassID
		)
	SET @count = @count + @@ROWCOUNT
	DROP TABLE #HardwareObject	-- Drop the temporary table
	COMMIT WORK
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[HardwareObjectRemoveBatch]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[HardwareObjectRemoveBatch]
GO

CREATE PROCEDURE [dbo].[HardwareObjectRemoveBatch]
AS

	CREATE INDEX [TempHardwareObjectHardwareObjectRemoveBatch]
		ON #HardwareObject (HardwareObjectID)	

	-- Delete records from HardwareObject identified by fields of [TempHardwareObjectHardwareObjectRemoveBatch]
	DELETE [dbo].[HardwareObject]
	WHERE EXISTS(
			SELECT * FROM #HardwareObject AS t
			WHERE	HardwareObject.HardwareObjectID = t.HardwareObjectID
		)
	DROP TABLE #HardwareObject      -- Drop the temporary table
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[HardwareObjectRemoveByComputerIDHardwareNameOccurrenceHardwareClassID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[HardwareObjectRemoveByComputerIDHardwareNameOccurrenceHardwareClassID]
GO
CREATE PROCEDURE [dbo].[HardwareObjectRemoveByComputerIDHardwareNameOccurrenceHardwareClassID]
	@ComputerID		int,
	@HardwareName		nvarchar(256),
	@Occurrence		int,
	@HardwareClassID	int
AS
	-- HardwareObject deletes cascade to:
	--	HardwareValue by FK_HardwareValue_HardwareObject
	DELETE	[dbo].[HardwareObject]
	WHERE	ComputerID = @ComputerID
	  AND	HardwareName = @HardwareName
	  AND	Occurrence = @Occurrence
	  AND	HardwareClassID = @HardwareClassID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[HardwareObjectRemoveAllByComputerID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[HardwareObjectRemoveAllByComputerID]
GO
CREATE PROCEDURE [dbo].[HardwareObjectRemoveAllByComputerID]
	@ComputerID		int
AS
	DELETE	[dbo].[HardwareObject]
	WHERE	ComputerID = @ComputerID
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[HardwareObjectRemoveAll]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[HardwareObjectRemoveAll]
GO
CREATE PROCEDURE [dbo].[HardwareObjectRemoveAll]
	
AS
	DELETE	[dbo].[HardwareObject]
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[HardwareObjectReplaceSubsetByComputerID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[HardwareObjectReplaceSubsetByComputerID]
GO
-- Replace the record subset selected by (@ComputerID)
-- using unique identifier (ComputerID, HardwareName, Occurrence, HardwareClassID)
CREATE PROCEDURE [dbo].[HardwareObjectReplaceSubsetByComputerID]
	@ComputerID		int
AS
	DECLARE @count AS int
	SET @count = 0

	CREATE INDEX [TempHardwareObjectByComputerID]
		ON #HardwareObject (ComputerID, HardwareName, Occurrence, HardwareClassID)

	BEGIN TRANSACTION
	DELETE [HardwareObject]
		WHERE	ComputerID = @ComputerID
		AND NOT EXISTS(		-- Replacement record doesn't exist
			SELECT * FROM #HardwareObject AS t
			WHERE	HardwareObject.ComputerID = t.ComputerID
			  AND	HardwareObject.HardwareName = t.HardwareName
			  AND	HardwareObject.Occurrence = t.Occurrence
			  AND	HardwareObject.HardwareClassID = t.HardwareClassID
		)

	INSERT [HardwareObject] (
		ComputerID,
		HardwareName,
		Occurrence,
		HardwareClassID
	)
		SELECT	ComputerID,
			HardwareName,
			Occurrence,
			HardwareClassID
		FROM	#HardwareObject AS t
		WHERE NOT EXISTS(	-- Current record doesn't exist
			SELECT * FROM [HardwareObject]
			WHERE	HardwareObject.ComputerID = t.ComputerID
			  AND	HardwareObject.HardwareName = t.HardwareName
			  AND	HardwareObject.Occurrence = t.Occurrence
			  AND	HardwareObject.HardwareClassID = t.HardwareClassID
		)
	SET @count = @count + @@ROWCOUNT
	DROP TABLE #HardwareObject	-- Drop the temporary table
	COMMIT WORK
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[HardwarePropertyGetByProperty]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[HardwarePropertyGetByProperty]
GO
CREATE PROCEDURE [dbo].[HardwarePropertyGetByProperty]
	@Property		nvarchar(256)
AS
	SELECT	HardwarePropertyID,
		Property
	FROM	[dbo].[HardwareProperty]
	WHERE	Property = @Property
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[HardwarePropertyGetByID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[HardwarePropertyGetByID]
GO
CREATE PROCEDURE [dbo].[HardwarePropertyGetByID]
	@HardwarePropertyID	int
AS
	SELECT	HardwarePropertyID,
		Property
	FROM	[dbo].[HardwareProperty]
	WHERE	HardwarePropertyID = @HardwarePropertyID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[HardwarePropertyGetAll]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[HardwarePropertyGetAll]
GO
CREATE PROCEDURE [dbo].[HardwarePropertyGetAll]
AS
	SELECT	HardwarePropertyID,
		Property
	FROM	[dbo].[HardwareProperty]
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[HardwarePropertyAdd]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[HardwarePropertyAdd]
GO
CREATE PROCEDURE [dbo].[HardwarePropertyAdd]
	@Property		nvarchar(256)
AS
	INSERT INTO  dbo.HardwareProperty (
		Property
	)
	VALUES (
		@Property
	)
	RETURN SCOPE_IDENTITY()
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[HardwarePropertyBind]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[HardwarePropertyBind]
GO
CREATE PROCEDURE [dbo].[HardwarePropertyBind]
	@Property		nvarchar(256)
AS
	DECLARE	@ID	int

	SELECT	@ID = HardwarePropertyID
	FROM	[dbo].[HardwareProperty]
	WHERE	Property = @Property

	IF @ID IS NULL
		EXEC @ID = HardwarePropertyAdd @Property

	RETURN @ID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[HardwarePropertySchema]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[HardwarePropertySchema]
GO
CREATE PROCEDURE [dbo].[HardwarePropertySchema]
AS
	SELECT
	'IF OBJECT_ID(''tempdb..#HardwareProperty'') IS NULL' + CAST(0x0A AS CHAR(1)) +
	'	CREATE TABLE #HardwareProperty (' + CAST(0x0A AS CHAR(1)) +
	'		HardwarePropertyID	int NULL,' + CAST(0x0A AS CHAR(1)) +
	'		Property		nvarchar(256) COLLATE database_default NOT NULL' + CAST(0x0A AS CHAR(1)) +
	'	)' + CAST(0x0A AS CHAR(1)) +
	'ELSE' + CAST(0x0A AS CHAR(1)) +
	'	DELETE FROM #HardwareProperty' + CAST(0x0A AS CHAR(1)) +
	'' AS SQL
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[HardwarePropertyTempAdd]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[HardwarePropertyTempAdd]
GO
CREATE PROCEDURE dbo.[HardwarePropertyTempAdd]
	@HardwarePropertyID	int,
	@Property		nvarchar(256)
AS
	INSERT INTO #HardwareProperty (
		HardwarePropertyID,
		Property
	)
	VALUES (
		@HardwarePropertyID,
		@Property
	)
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[HardwarePropertyAddBatch]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[HardwarePropertyAddBatch]
GO
CREATE PROCEDURE dbo.[HardwarePropertyAddBatch]
AS
	DECLARE @count int
	INSERT dbo.HardwareProperty (
		Property
	)
		SELECT	Property
		FROM #HardwareProperty
	SET @count = @@ROWCOUNT
	DROP TABLE #HardwareProperty	-- Drop temporary table
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[HardwarePropertyUpdateByID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[HardwarePropertyUpdateByID]
GO
CREATE PROCEDURE [dbo].[HardwarePropertyUpdateByID]
	@HardwarePropertyID	int,
	@Property		nvarchar(256)
AS
	DECLARE	@ID	int
	SET @ID = 0

	UPDATE	[dbo].[HardwareProperty]
	SET	@ID = HardwarePropertyID,
		Property = @Property
	WHERE	HardwarePropertyID = @HardwarePropertyID
	RETURN @ID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[HardwarePropertyUpdateBatchByID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[HardwarePropertyUpdateBatchByID]
GO
CREATE PROCEDURE dbo.[HardwarePropertyUpdateBatchByID]
AS
	DECLARE @count int

	CREATE INDEX [TempHardwarePropertyID]
		ON #HardwareProperty (HardwarePropertyID)

	UPDATE	[dbo].[HardwareProperty]
	SET	Property = t.Property
	FROM	#HardwareProperty AS t
	WHERE	HardwareProperty.HardwarePropertyID = t.HardwarePropertyID
	SET @count = @@ROWCOUNT
	DROP TABLE #HardwareProperty	-- Drop the temporary table
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[HardwarePropertyPutByProperty]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[HardwarePropertyPutByProperty]
GO
CREATE PROCEDURE [dbo].[HardwarePropertyPutByProperty]
	@Property		nvarchar(256)
AS
	DECLARE @ID	int

	SELECT	@ID = HardwarePropertyID
	FROM	HardwareProperty
	WHERE	Property = @Property

	IF @ID IS NULL
		EXEC @ID = HardwarePropertyAdd @Property

	RETURN @ID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[HardwarePropertyPutBatchByProperty]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[HardwarePropertyPutBatchByProperty]
GO
CREATE PROCEDURE [dbo].[HardwarePropertyPutBatchByProperty]
AS
	DECLARE @count AS int
	SET @count = 0

	CREATE INDEX [TempHardwarePropertyProperty]
		ON #HardwareProperty (Property)

	BEGIN TRANSACTION

	INSERT [dbo].[HardwareProperty] (
		Property
	)
		SELECT	Property
		FROM	#HardwareProperty AS t
		WHERE NOT EXISTS(	-- Current record doesn't exist
			SELECT * FROM [dbo].[HardwareProperty]
			WHERE	HardwareProperty.Property = t.Property
		)
	SET @count = @count + @@ROWCOUNT
	DROP TABLE #HardwareProperty	-- Drop the temporary table
	COMMIT WORK
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[HardwarePropertyRemoveBatch]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[HardwarePropertyRemoveBatch]
GO

CREATE PROCEDURE [dbo].[HardwarePropertyRemoveBatch]
AS

	CREATE INDEX [TempHardwarePropertyHardwarePropertyRemoveBatch]
		ON #HardwareProperty (HardwarePropertyID)	

	-- Delete records from HardwareProperty identified by fields of [TempHardwarePropertyHardwarePropertyRemoveBatch]
	DELETE [dbo].[HardwareProperty]
	WHERE EXISTS(
			SELECT * FROM #HardwareProperty AS t
			WHERE	HardwareProperty.HardwarePropertyID = t.HardwarePropertyID
		)
	DROP TABLE #HardwareProperty      -- Drop the temporary table
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[HardwarePropertyRemoveByProperty]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[HardwarePropertyRemoveByProperty]
GO
CREATE PROCEDURE [dbo].[HardwarePropertyRemoveByProperty]
	@Property		nvarchar(256)
AS
	-- HardwareProperty deletes cascade to:
	--	HardwareValue by FK_HardwareValue_HardwareProperty
	DELETE	[dbo].[HardwareProperty]
	WHERE	Property = @Property
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[HardwarePropertyRemoveAll]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[HardwarePropertyRemoveAll]
GO
CREATE PROCEDURE [dbo].[HardwarePropertyRemoveAll]
	
AS
	DELETE	[dbo].[HardwareProperty]
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[HardwareValueGetByHardwareObjectIDHardwarePropertyID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[HardwareValueGetByHardwareObjectIDHardwarePropertyID]
GO
CREATE PROCEDURE [dbo].[HardwareValueGetByHardwareObjectIDHardwarePropertyID]
	@HardwareObjectID	int,
	@HardwarePropertyID	int
AS
	SELECT	HardwareObjectID,
		HardwarePropertyID,
		Value
	FROM	[dbo].[HardwareValue]
	WHERE	HardwareObjectID = @HardwareObjectID
	  AND	HardwarePropertyID = @HardwarePropertyID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[HardwareValueGetAllByHardwareObjectID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[HardwareValueGetAllByHardwareObjectID]
GO
CREATE PROCEDURE [dbo].[HardwareValueGetAllByHardwareObjectID]
	@HardwareObjectID	int
AS
	SELECT	HardwareObjectID,
		HardwarePropertyID,
		Value
	FROM	[dbo].[HardwareValue]
	WHERE	HardwareObjectID = @HardwareObjectID
	ORDER BY HardwarePropertyID
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[HardwareValueGetAll]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[HardwareValueGetAll]
GO
CREATE PROCEDURE [dbo].[HardwareValueGetAll]
AS
	SELECT	HardwareObjectID,
		HardwarePropertyID,
		Value
	FROM	[dbo].[HardwareValue]
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[HardwareValueAdd]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[HardwareValueAdd]
GO
CREATE PROCEDURE [dbo].[HardwareValueAdd]
	@HardwareObjectID	int,
	@HardwarePropertyID	int,
	@Value			nvarchar(256) = NULL
AS
	INSERT INTO  dbo.HardwareValue (
		HardwareObjectID,
		HardwarePropertyID,
		Value
	)
	VALUES (
		@HardwareObjectID,
		@HardwarePropertyID,
		@Value
	)
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[HardwareValueSchema]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[HardwareValueSchema]
GO
CREATE PROCEDURE [dbo].[HardwareValueSchema]
AS
	SELECT
	'IF OBJECT_ID(''tempdb..#HardwareValue'') IS NULL' + CAST(0x0A AS CHAR(1)) +
	'	CREATE TABLE #HardwareValue (' + CAST(0x0A AS CHAR(1)) +
	'		HardwareObjectID	int NOT NULL,' + CAST(0x0A AS CHAR(1)) +
	'		HardwarePropertyID	int NOT NULL,' + CAST(0x0A AS CHAR(1)) +
	'		Value			nvarchar(256) COLLATE database_default NULL' + CAST(0x0A AS CHAR(1)) +
	'	)' + CAST(0x0A AS CHAR(1)) +
	'ELSE' + CAST(0x0A AS CHAR(1)) +
	'	DELETE FROM #HardwareValue' + CAST(0x0A AS CHAR(1)) +
	'' AS SQL
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[HardwareValueTempAdd]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[HardwareValueTempAdd]
GO
CREATE PROCEDURE dbo.[HardwareValueTempAdd]
	@HardwareObjectID	int,
	@HardwarePropertyID	int,
	@Value			nvarchar(256) = NULL
AS
	INSERT INTO #HardwareValue (
		HardwareObjectID,
		HardwarePropertyID,
		Value
	)
	VALUES (
		@HardwareObjectID,
		@HardwarePropertyID,
		@Value
	)
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[HardwareValueAddBatch]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[HardwareValueAddBatch]
GO
CREATE PROCEDURE dbo.[HardwareValueAddBatch]
AS
	DECLARE @count int
	INSERT dbo.HardwareValue (
		HardwareObjectID,
		HardwarePropertyID,
		Value
	)
		SELECT	HardwareObjectID,
			HardwarePropertyID,
			Value
		FROM #HardwareValue
	SET @count = @@ROWCOUNT
	DROP TABLE #HardwareValue	-- Drop temporary table
	RETURN @count
GO

/*
Add new HardwareValue bound to
	HardwareObject using ComputerID, HardwareName, Occurrence, HardwareClassID
	HardwareProperty using Property
	with Value
*/

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[HardwareValueUpdateByHardwareObjectIDHardwarePropertyID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[HardwareValueUpdateByHardwareObjectIDHardwarePropertyID]
GO
CREATE PROCEDURE [dbo].[HardwareValueUpdateByHardwareObjectIDHardwarePropertyID]
	@HardwareObjectID	int,
	@HardwarePropertyID	int,
	@Value			nvarchar(256) = NULL
AS
	UPDATE	[dbo].[HardwareValue]
	SET	Value = @Value
	WHERE	HardwareObjectID = @HardwareObjectID
	  AND	HardwarePropertyID = @HardwarePropertyID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[HardwareValueUpdateBatchByHardwareObjectIDHardwarePropertyID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[HardwareValueUpdateBatchByHardwareObjectIDHardwarePropertyID]
GO
CREATE PROCEDURE dbo.[HardwareValueUpdateBatchByHardwareObjectIDHardwarePropertyID]
AS
	DECLARE @count int

	CREATE INDEX [TempHardwareValueHardwareObjectIDHardwarePropertyID]
		ON #HardwareValue (HardwareObjectID, HardwarePropertyID)

	UPDATE	[dbo].[HardwareValue]
	SET	Value = t.Value
	FROM	#HardwareValue AS t
	WHERE	HardwareValue.HardwareObjectID = t.HardwareObjectID
	  AND	HardwareValue.HardwarePropertyID = t.HardwarePropertyID
	SET @count = @@ROWCOUNT
	DROP TABLE #HardwareValue	-- Drop the temporary table
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[HardwareValuePutByHardwareObjectIDHardwarePropertyID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[HardwareValuePutByHardwareObjectIDHardwarePropertyID]
GO
CREATE PROCEDURE [dbo].[HardwareValuePutByHardwareObjectIDHardwarePropertyID]
	@HardwareObjectID	int,
	@HardwarePropertyID	int,
	@Value			nvarchar(256) = NULL
AS
	IF NOT EXISTS(
		SELECT	1
		FROM	dbo.HardwareValue
		WHERE	HardwareObjectID = @HardwareObjectID
		  AND	HardwarePropertyID = @HardwarePropertyID
	)
		EXEC HardwareValueAdd @HardwareObjectID,
			@HardwarePropertyID,
			@Value
	ELSE
		EXEC HardwareValueUpdateByHardwareObjectIDHardwarePropertyID @HardwareObjectID,
			@HardwarePropertyID,
			@Value
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[HardwareValuePutBatchByHardwareObjectIDHardwarePropertyID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[HardwareValuePutBatchByHardwareObjectIDHardwarePropertyID]
GO
CREATE PROCEDURE [dbo].[HardwareValuePutBatchByHardwareObjectIDHardwarePropertyID]
AS
	DECLARE @count AS int
	SET @count = 0

	CREATE INDEX [TempHardwareValueHardwareObjectIDHardwarePropertyID]
		ON #HardwareValue (HardwareObjectID, HardwarePropertyID)

	BEGIN TRANSACTION
	UPDATE [dbo].[HardwareValue]
		SET	Value = t.Value
		FROM	#HardwareValue AS t
		WHERE	HardwareValue.HardwareObjectID = t.HardwareObjectID
		  AND	HardwareValue.HardwarePropertyID = t.HardwarePropertyID
	SET @count = @@ROWCOUNT

	INSERT [dbo].[HardwareValue] (
		HardwareObjectID,
		HardwarePropertyID,
		Value
	)
		SELECT	HardwareObjectID,
			HardwarePropertyID,
			Value
		FROM	#HardwareValue AS t
		WHERE NOT EXISTS(	-- Current record doesn't exist
			SELECT * FROM [dbo].[HardwareValue]
			WHERE	HardwareValue.HardwareObjectID = t.HardwareObjectID
			  AND	HardwareValue.HardwarePropertyID = t.HardwarePropertyID
		)
	SET @count = @count + @@ROWCOUNT
	DROP TABLE #HardwareValue	-- Drop the temporary table
	COMMIT WORK
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[HardwareValueRemoveBatch]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[HardwareValueRemoveBatch]
GO

CREATE PROCEDURE [dbo].[HardwareValueRemoveBatch]
AS

	CREATE INDEX [TempHardwareValueHardwareValueRemoveBatch]
		ON #HardwareValue (HardwareObjectID, HardwarePropertyID)	

	-- Delete records from HardwareValue identified by fields of [TempHardwareValueHardwareValueRemoveBatch]
	DELETE [dbo].[HardwareValue]
	WHERE EXISTS(
			SELECT * FROM #HardwareValue AS t
			WHERE	HardwareValue.HardwareObjectID = t.HardwareObjectID
			  AND	HardwareValue.HardwarePropertyID = t.HardwarePropertyID
		)
	DROP TABLE #HardwareValue      -- Drop the temporary table
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[HardwareValueRemoveByHardwareObjectIDHardwarePropertyID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[HardwareValueRemoveByHardwareObjectIDHardwarePropertyID]
GO
CREATE PROCEDURE [dbo].[HardwareValueRemoveByHardwareObjectIDHardwarePropertyID]
	@HardwareObjectID	int,
	@HardwarePropertyID	int
AS
	DELETE	[dbo].[HardwareValue]
	WHERE	HardwareObjectID = @HardwareObjectID
	  AND	HardwarePropertyID = @HardwarePropertyID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[HardwareValueRemoveAllByHardwareObjectID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[HardwareValueRemoveAllByHardwareObjectID]
GO
CREATE PROCEDURE [dbo].[HardwareValueRemoveAllByHardwareObjectID]
	@HardwareObjectID	int
AS
	DELETE	[dbo].[HardwareValue]
	WHERE	HardwareObjectID = @HardwareObjectID
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[HardwareValueRemoveAll]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[HardwareValueRemoveAll]
GO
CREATE PROCEDURE [dbo].[HardwareValueRemoveAll]
	
AS
	DELETE	[dbo].[HardwareValue]
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[HardwareValueReplaceSubsetByHardwareObjectID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[HardwareValueReplaceSubsetByHardwareObjectID]
GO
-- Replace the record subset selected by (@HardwareObjectID)
-- using unique identifier (HardwareObjectID, HardwarePropertyID)
-- updating fields (Value)
CREATE PROCEDURE [dbo].[HardwareValueReplaceSubsetByHardwareObjectID]
	@HardwareObjectID	int
AS
	DECLARE @count AS int
	SET @count = 0

	CREATE INDEX [TempHardwareValueByHardwareObjectID]
		ON #HardwareValue (HardwareObjectID, HardwarePropertyID)

	BEGIN TRANSACTION
	DELETE [HardwareValue]
		WHERE	HardwareObjectID = @HardwareObjectID
		AND NOT EXISTS(		-- Replacement record doesn't exist
			SELECT * FROM #HardwareValue AS t
			WHERE	HardwareValue.HardwareObjectID = t.HardwareObjectID
			  AND	HardwareValue.HardwarePropertyID = t.HardwarePropertyID
		)

	UPDATE [dbo].[HardwareValue]
		SET	Value = t.Value
		FROM	#HardwareValue AS t
		WHERE	HardwareValue.HardwareObjectID = t.HardwareObjectID
		  AND	HardwareValue.HardwarePropertyID = t.HardwarePropertyID
	SET @count = @@ROWCOUNT

	INSERT [HardwareValue] (
		HardwareObjectID,
		HardwarePropertyID,
		Value
	)
		SELECT	HardwareObjectID,
			HardwarePropertyID,
			Value
		FROM	#HardwareValue AS t
		WHERE NOT EXISTS(	-- Current record doesn't exist
			SELECT * FROM [HardwareValue]
			WHERE	HardwareValue.HardwareObjectID = t.HardwareObjectID
			  AND	HardwareValue.HardwarePropertyID = t.HardwarePropertyID
		)
	SET @count = @count + @@ROWCOUNT
	DROP TABLE #HardwareValue	-- Drop the temporary table
	COMMIT WORK
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ServiceProviderNameGetByName]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ServiceProviderNameGetByName]
GO
CREATE PROCEDURE [dbo].[ServiceProviderNameGetByName]
	@Name			nvarchar(128)
AS
	SELECT	ServiceProviderNameID,
		[Name]
	FROM	[dbo].[ServiceProviderName]
	WHERE	[Name] = @Name
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ServiceProviderNameGetByID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ServiceProviderNameGetByID]
GO
CREATE PROCEDURE [dbo].[ServiceProviderNameGetByID]
	@ServiceProviderNameID	int
AS
	SELECT	ServiceProviderNameID,
		[Name]
	FROM	[dbo].[ServiceProviderName]
	WHERE	ServiceProviderNameID = @ServiceProviderNameID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ServiceProviderNameGetAll]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ServiceProviderNameGetAll]
GO
CREATE PROCEDURE [dbo].[ServiceProviderNameGetAll]
AS
	SELECT	ServiceProviderNameID,
		[Name]
	FROM	[dbo].[ServiceProviderName]
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ServiceProviderNameAdd]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ServiceProviderNameAdd]
GO
CREATE PROCEDURE [dbo].[ServiceProviderNameAdd]
	@Name			nvarchar(128)
AS
	INSERT INTO  dbo.ServiceProviderName (
		[Name]
	)
	VALUES (
		@Name
	)
	RETURN SCOPE_IDENTITY()
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ServiceProviderNameBind]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ServiceProviderNameBind]
GO
CREATE PROCEDURE [dbo].[ServiceProviderNameBind]
	@Name			nvarchar(128)
AS
	DECLARE	@ID	int

	SELECT	@ID = ServiceProviderNameID
	FROM	[dbo].[ServiceProviderName]
	WHERE	[Name] = @Name

	IF @ID IS NULL
		EXEC @ID = ServiceProviderNameAdd @Name

	RETURN @ID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ServiceProviderNameSchema]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ServiceProviderNameSchema]
GO
CREATE PROCEDURE [dbo].[ServiceProviderNameSchema]
AS
	SELECT
	'IF OBJECT_ID(''tempdb..#ServiceProviderName'') IS NULL' + CAST(0x0A AS CHAR(1)) +
	'	CREATE TABLE #ServiceProviderName (' + CAST(0x0A AS CHAR(1)) +
	'		ServiceProviderNameID	int NULL,' + CAST(0x0A AS CHAR(1)) +
	'		[Name]			nvarchar(128) COLLATE database_default NOT NULL' + CAST(0x0A AS CHAR(1)) +
	'	)' + CAST(0x0A AS CHAR(1)) +
	'ELSE' + CAST(0x0A AS CHAR(1)) +
	'	DELETE FROM #ServiceProviderName' + CAST(0x0A AS CHAR(1)) +
	'' AS SQL
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ServiceProviderNameTempAdd]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ServiceProviderNameTempAdd]
GO
CREATE PROCEDURE dbo.[ServiceProviderNameTempAdd]
	@ServiceProviderNameID	int,
	@Name			nvarchar(128)
AS
	INSERT INTO #ServiceProviderName (
		ServiceProviderNameID,
		[Name]
	)
	VALUES (
		@ServiceProviderNameID,
		@Name
	)
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ServiceProviderNameAddBatch]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ServiceProviderNameAddBatch]
GO
CREATE PROCEDURE dbo.[ServiceProviderNameAddBatch]
AS
	DECLARE @count int
	INSERT dbo.ServiceProviderName (
		[Name]
	)
		SELECT	[Name]
		FROM #ServiceProviderName
	SET @count = @@ROWCOUNT
	DROP TABLE #ServiceProviderName	-- Drop temporary table
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ServiceProviderNameUpdateByID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ServiceProviderNameUpdateByID]
GO
CREATE PROCEDURE [dbo].[ServiceProviderNameUpdateByID]
	@ServiceProviderNameID	int,
	@Name			nvarchar(128)
AS
	DECLARE	@ID	int
	SET @ID = 0

	UPDATE	[dbo].[ServiceProviderName]
	SET	@ID = ServiceProviderNameID,
		[Name] = @Name
	WHERE	ServiceProviderNameID = @ServiceProviderNameID
	RETURN @ID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ServiceProviderNameUpdateBatchByID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ServiceProviderNameUpdateBatchByID]
GO
CREATE PROCEDURE dbo.[ServiceProviderNameUpdateBatchByID]
AS
	DECLARE @count int

	CREATE INDEX [TempServiceProviderNameID]
		ON #ServiceProviderName (ServiceProviderNameID)

	UPDATE	[dbo].[ServiceProviderName]
	SET	[Name] = t.[Name]
	FROM	#ServiceProviderName AS t
	WHERE	ServiceProviderName.ServiceProviderNameID = t.ServiceProviderNameID
	SET @count = @@ROWCOUNT
	DROP TABLE #ServiceProviderName	-- Drop the temporary table
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ServiceProviderNamePutByName]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ServiceProviderNamePutByName]
GO
CREATE PROCEDURE [dbo].[ServiceProviderNamePutByName]
	@Name			nvarchar(128)
AS
	DECLARE @ID	int

	SELECT	@ID = ServiceProviderNameID
	FROM	ServiceProviderName
	WHERE	[Name] = @Name

	IF @ID IS NULL
		EXEC @ID = ServiceProviderNameAdd @Name

	RETURN @ID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ServiceProviderNamePutBatchByName]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ServiceProviderNamePutBatchByName]
GO
CREATE PROCEDURE [dbo].[ServiceProviderNamePutBatchByName]
AS
	DECLARE @count AS int
	SET @count = 0

	CREATE INDEX [TempServiceProviderNameName]
		ON #ServiceProviderName ([Name])

	BEGIN TRANSACTION

	INSERT [dbo].[ServiceProviderName] (
		[Name]
	)
		SELECT	[Name]
		FROM	#ServiceProviderName AS t
		WHERE NOT EXISTS(	-- Current record doesn't exist
			SELECT * FROM [dbo].[ServiceProviderName]
			WHERE	ServiceProviderName.[Name] = t.[Name]
		)
	SET @count = @count + @@ROWCOUNT
	DROP TABLE #ServiceProviderName	-- Drop the temporary table
	COMMIT WORK
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ServiceProviderNameRemoveBatch]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ServiceProviderNameRemoveBatch]
GO

CREATE PROCEDURE [dbo].[ServiceProviderNameRemoveBatch]
AS

	CREATE INDEX [TempServiceProviderNameServiceProviderNameRemoveBatch]
		ON #ServiceProviderName (ServiceProviderNameID)	

	-- Delete records from ServiceProviderName identified by fields of [TempServiceProviderNameServiceProviderNameRemoveBatch]
	DELETE [dbo].[ServiceProviderName]
	WHERE EXISTS(
			SELECT * FROM #ServiceProviderName AS t
			WHERE	ServiceProviderName.ServiceProviderNameID = t.ServiceProviderNameID
		)
	DROP TABLE #ServiceProviderName      -- Drop the temporary table
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ServiceProviderNameRemoveByName]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ServiceProviderNameRemoveByName]
GO
CREATE PROCEDURE [dbo].[ServiceProviderNameRemoveByName]
	@Name			nvarchar(128)
AS
	-- ServiceProviderName deletes may fail due to non-cascading FKs:
	--	ServiceProvider by FK_ServiceProvider_ServiceProviderName
	DELETE	[dbo].[ServiceProviderName]
	WHERE	[Name] = @Name
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ServiceProviderNameRemoveAll]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ServiceProviderNameRemoveAll]
GO
CREATE PROCEDURE [dbo].[ServiceProviderNameRemoveAll]
	
AS
	DELETE	[dbo].[ServiceProviderName]
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ServiceProviderTypeGetByType]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ServiceProviderTypeGetByType]
GO
CREATE PROCEDURE [dbo].[ServiceProviderTypeGetByType]
	@Type			nvarchar(128)
AS
	SELECT	ServiceProviderTypeID,
		Type
	FROM	[dbo].[ServiceProviderType]
	WHERE	Type = @Type
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ServiceProviderTypeGetByID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ServiceProviderTypeGetByID]
GO
CREATE PROCEDURE [dbo].[ServiceProviderTypeGetByID]
	@ServiceProviderTypeID	int
AS
	SELECT	ServiceProviderTypeID,
		Type
	FROM	[dbo].[ServiceProviderType]
	WHERE	ServiceProviderTypeID = @ServiceProviderTypeID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ServiceProviderTypeGetAll]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ServiceProviderTypeGetAll]
GO
CREATE PROCEDURE [dbo].[ServiceProviderTypeGetAll]
AS
	SELECT	ServiceProviderTypeID,
		Type
	FROM	[dbo].[ServiceProviderType]
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ServiceProviderTypeAdd]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ServiceProviderTypeAdd]
GO
CREATE PROCEDURE [dbo].[ServiceProviderTypeAdd]
	@Type			nvarchar(128)
AS
	INSERT INTO  dbo.ServiceProviderType (
		Type
	)
	VALUES (
		@Type
	)
	RETURN SCOPE_IDENTITY()
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ServiceProviderTypeBind]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ServiceProviderTypeBind]
GO
CREATE PROCEDURE [dbo].[ServiceProviderTypeBind]
	@Type			nvarchar(128)
AS
	DECLARE	@ID	int

	SELECT	@ID = ServiceProviderTypeID
	FROM	[dbo].[ServiceProviderType]
	WHERE	Type = @Type

	IF @ID IS NULL
		EXEC @ID = ServiceProviderTypeAdd @Type

	RETURN @ID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ServiceProviderTypeSchema]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ServiceProviderTypeSchema]
GO
CREATE PROCEDURE [dbo].[ServiceProviderTypeSchema]
AS
	SELECT
	'IF OBJECT_ID(''tempdb..#ServiceProviderType'') IS NULL' + CAST(0x0A AS CHAR(1)) +
	'	CREATE TABLE #ServiceProviderType (' + CAST(0x0A AS CHAR(1)) +
	'		ServiceProviderTypeID	int NULL,' + CAST(0x0A AS CHAR(1)) +
	'		Type			nvarchar(128) COLLATE database_default NOT NULL' + CAST(0x0A AS CHAR(1)) +
	'	)' + CAST(0x0A AS CHAR(1)) +
	'ELSE' + CAST(0x0A AS CHAR(1)) +
	'	DELETE FROM #ServiceProviderType' + CAST(0x0A AS CHAR(1)) +
	'' AS SQL
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ServiceProviderTypeTempAdd]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ServiceProviderTypeTempAdd]
GO
CREATE PROCEDURE dbo.[ServiceProviderTypeTempAdd]
	@ServiceProviderTypeID	int,
	@Type			nvarchar(128)
AS
	INSERT INTO #ServiceProviderType (
		ServiceProviderTypeID,
		Type
	)
	VALUES (
		@ServiceProviderTypeID,
		@Type
	)
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ServiceProviderTypeAddBatch]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ServiceProviderTypeAddBatch]
GO
CREATE PROCEDURE dbo.[ServiceProviderTypeAddBatch]
AS
	DECLARE @count int
	INSERT dbo.ServiceProviderType (
		Type
	)
		SELECT	Type
		FROM #ServiceProviderType
	SET @count = @@ROWCOUNT
	DROP TABLE #ServiceProviderType	-- Drop temporary table
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ServiceProviderTypeUpdateByID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ServiceProviderTypeUpdateByID]
GO
CREATE PROCEDURE [dbo].[ServiceProviderTypeUpdateByID]
	@ServiceProviderTypeID	int,
	@Type			nvarchar(128)
AS
	DECLARE	@ID	int
	SET @ID = 0

	UPDATE	[dbo].[ServiceProviderType]
	SET	@ID = ServiceProviderTypeID,
		Type = @Type
	WHERE	ServiceProviderTypeID = @ServiceProviderTypeID
	RETURN @ID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ServiceProviderTypeUpdateBatchByID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ServiceProviderTypeUpdateBatchByID]
GO
CREATE PROCEDURE dbo.[ServiceProviderTypeUpdateBatchByID]
AS
	DECLARE @count int

	CREATE INDEX [TempServiceProviderTypeID]
		ON #ServiceProviderType (ServiceProviderTypeID)

	UPDATE	[dbo].[ServiceProviderType]
	SET	Type = t.Type
	FROM	#ServiceProviderType AS t
	WHERE	ServiceProviderType.ServiceProviderTypeID = t.ServiceProviderTypeID
	SET @count = @@ROWCOUNT
	DROP TABLE #ServiceProviderType	-- Drop the temporary table
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ServiceProviderTypePutByType]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ServiceProviderTypePutByType]
GO
CREATE PROCEDURE [dbo].[ServiceProviderTypePutByType]
	@Type			nvarchar(128)
AS
	DECLARE @ID	int

	SELECT	@ID = ServiceProviderTypeID
	FROM	ServiceProviderType
	WHERE	Type = @Type

	IF @ID IS NULL
		EXEC @ID = ServiceProviderTypeAdd @Type

	RETURN @ID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ServiceProviderTypePutBatchByType]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ServiceProviderTypePutBatchByType]
GO
CREATE PROCEDURE [dbo].[ServiceProviderTypePutBatchByType]
AS
	DECLARE @count AS int
	SET @count = 0

	CREATE INDEX [TempServiceProviderTypeType]
		ON #ServiceProviderType (Type)

	BEGIN TRANSACTION

	INSERT [dbo].[ServiceProviderType] (
		Type
	)
		SELECT	Type
		FROM	#ServiceProviderType AS t
		WHERE NOT EXISTS(	-- Current record doesn't exist
			SELECT * FROM [dbo].[ServiceProviderType]
			WHERE	ServiceProviderType.Type = t.Type
		)
	SET @count = @count + @@ROWCOUNT
	DROP TABLE #ServiceProviderType	-- Drop the temporary table
	COMMIT WORK
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ServiceProviderTypeRemoveBatch]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ServiceProviderTypeRemoveBatch]
GO

CREATE PROCEDURE [dbo].[ServiceProviderTypeRemoveBatch]
AS

	CREATE INDEX [TempServiceProviderTypeServiceProviderTypeRemoveBatch]
		ON #ServiceProviderType (ServiceProviderTypeID)	

	-- Delete records from ServiceProviderType identified by fields of [TempServiceProviderTypeServiceProviderTypeRemoveBatch]
	DELETE [dbo].[ServiceProviderType]
	WHERE EXISTS(
			SELECT * FROM #ServiceProviderType AS t
			WHERE	ServiceProviderType.ServiceProviderTypeID = t.ServiceProviderTypeID
		)
	DROP TABLE #ServiceProviderType      -- Drop the temporary table
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ServiceProviderTypeRemoveByType]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ServiceProviderTypeRemoveByType]
GO
CREATE PROCEDURE [dbo].[ServiceProviderTypeRemoveByType]
	@Type			nvarchar(128)
AS
	-- ServiceProviderType deletes may fail due to non-cascading FKs:
	--	ServiceProvider by FK_ServiceProvider_ServiceProviderType
	DELETE	[dbo].[ServiceProviderType]
	WHERE	Type = @Type
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ServiceProviderTypeRemoveAll]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ServiceProviderTypeRemoveAll]
GO
CREATE PROCEDURE [dbo].[ServiceProviderTypeRemoveAll]
	
AS
	DELETE	[dbo].[ServiceProviderType]
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ServiceProviderGetByComputerIDTypeIDNameID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ServiceProviderGetByComputerIDTypeIDNameID]
GO
CREATE PROCEDURE [dbo].[ServiceProviderGetByComputerIDTypeIDNameID]
	@ComputerID		int,
	@ServiceProviderTypeID	int,
	@ServiceProviderNameID	int
AS
	SELECT	ServiceProviderID,
		ComputerID,
		ParentServiceProviderID,
		ServiceProviderTypeID,
		ServiceProviderNameID,
		LastInventoryDate,
		LastInventoryResult,
		LastInventoryError,
		CreationDate
	FROM	[dbo].[ServiceProvider]
	WHERE	ComputerID = @ComputerID
	  AND	ServiceProviderTypeID = @ServiceProviderTypeID
	  AND	ServiceProviderNameID = @ServiceProviderNameID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ServiceProviderGetAllByComputerID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ServiceProviderGetAllByComputerID]
GO
CREATE PROCEDURE [dbo].[ServiceProviderGetAllByComputerID]
	@ComputerID		int
AS
	SELECT	ServiceProviderID,
		ComputerID,
		ParentServiceProviderID,
		ServiceProviderTypeID,
		ServiceProviderNameID,
		LastInventoryDate,
		LastInventoryResult,
		LastInventoryError,
		CreationDate
	FROM	[dbo].[ServiceProvider]
	WHERE	ComputerID = @ComputerID
	ORDER BY ServiceProviderTypeID, ServiceProviderNameID
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ServiceProviderGetByID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ServiceProviderGetByID]
GO
CREATE PROCEDURE [dbo].[ServiceProviderGetByID]
	@ServiceProviderID	int
AS
	SELECT	ServiceProviderID,
		ComputerID,
		ParentServiceProviderID,
		ServiceProviderTypeID,
		ServiceProviderNameID,
		LastInventoryDate,
		LastInventoryResult,
		LastInventoryError,
		CreationDate
	FROM	[dbo].[ServiceProvider]
	WHERE	ServiceProviderID = @ServiceProviderID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ServiceProviderGetAll]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ServiceProviderGetAll]
GO
CREATE PROCEDURE [dbo].[ServiceProviderGetAll]
AS
	SELECT	ServiceProviderID,
		ComputerID,
		ParentServiceProviderID,
		ServiceProviderTypeID,
		ServiceProviderNameID,
		LastInventoryDate,
		LastInventoryResult,
		LastInventoryError,
		CreationDate
	FROM	[dbo].[ServiceProvider]
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ServiceProviderAdd]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ServiceProviderAdd]
GO
CREATE PROCEDURE [dbo].[ServiceProviderAdd]
	@ComputerID		int,
	@ParentServiceProviderID int = NULL,
	@ServiceProviderTypeID	int,
	@ServiceProviderNameID	int,
	@LastInventoryDate	datetime,
	@LastInventoryResult	int = NULL,
	@LastInventoryError	nvarchar(256) = NULL,
	@CreationDate		datetime = NULL
AS
	INSERT INTO  dbo.ServiceProvider (
		ComputerID,
		ParentServiceProviderID,
		ServiceProviderTypeID,
		ServiceProviderNameID,
		LastInventoryDate,
		LastInventoryResult,
		LastInventoryError,
		CreationDate
	)
	VALUES (
		@ComputerID,
		@ParentServiceProviderID,
		@ServiceProviderTypeID,
		@ServiceProviderNameID,
		@LastInventoryDate,
		@LastInventoryResult,
		@LastInventoryError,
		@CreationDate
	)
	RETURN SCOPE_IDENTITY()
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ServiceProviderBind]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ServiceProviderBind]
GO
CREATE PROCEDURE [dbo].[ServiceProviderBind]
	@ComputerID		int,
	@ParentServiceProviderID int = NULL,
	@ServiceProviderTypeID	int,
	@ServiceProviderNameID	int,
	@LastInventoryDate	datetime,
	@LastInventoryResult	int = NULL,
	@LastInventoryError	nvarchar(256) = NULL,
	@CreationDate		datetime = NULL
AS
	DECLARE	@ID	int

	SELECT	@ID = ServiceProviderID
	FROM	[dbo].[ServiceProvider]
	WHERE	ComputerID = @ComputerID
	  AND	ServiceProviderTypeID = @ServiceProviderTypeID
	  AND	ServiceProviderNameID = @ServiceProviderNameID

	IF @ID IS NULL
		EXEC @ID = ServiceProviderAdd @ComputerID,
			@ParentServiceProviderID,
			@ServiceProviderTypeID,
			@ServiceProviderNameID,
			@LastInventoryDate,
			@LastInventoryResult,
			@LastInventoryError,
			@CreationDate

	RETURN @ID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ServiceProviderSchema]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ServiceProviderSchema]
GO
CREATE PROCEDURE [dbo].[ServiceProviderSchema]
AS
	SELECT
	'IF OBJECT_ID(''tempdb..#ServiceProvider'') IS NULL' + CAST(0x0A AS CHAR(1)) +
	'	CREATE TABLE #ServiceProvider (' + CAST(0x0A AS CHAR(1)) +
	'		ServiceProviderID	int NULL,' + CAST(0x0A AS CHAR(1)) +
	'		ComputerID		int NOT NULL,' + CAST(0x0A AS CHAR(1)) +
	'		ParentServiceProviderID	int NULL,' + CAST(0x0A AS CHAR(1)) +
	'		ServiceProviderTypeID	int NOT NULL,' + CAST(0x0A AS CHAR(1)) +
	'		ServiceProviderNameID	int NOT NULL,' + CAST(0x0A AS CHAR(1)) +
	'		LastInventoryDate	datetime NOT NULL DEFAULT getdate(),' + CAST(0x0A AS CHAR(1)) +
	'		LastInventoryResult	int NULL,' + CAST(0x0A AS CHAR(1)) +
	'		LastInventoryError	nvarchar(256) COLLATE database_default NULL,' + CAST(0x0A AS CHAR(1)) +
	'		CreationDate		datetime NULL' + CAST(0x0A AS CHAR(1)) +
	'	)' + CAST(0x0A AS CHAR(1)) +
	'ELSE' + CAST(0x0A AS CHAR(1)) +
	'	DELETE FROM #ServiceProvider' + CAST(0x0A AS CHAR(1)) +
	'' AS SQL
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ServiceProviderTempAdd]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ServiceProviderTempAdd]
GO
CREATE PROCEDURE dbo.[ServiceProviderTempAdd]
	@ServiceProviderID	int,
	@ComputerID		int,
	@ParentServiceProviderID int = NULL,
	@ServiceProviderTypeID	int,
	@ServiceProviderNameID	int,
	@LastInventoryDate	datetime,
	@LastInventoryResult	int = NULL,
	@LastInventoryError	nvarchar(256) = NULL,
	@CreationDate		datetime = NULL
AS
	INSERT INTO #ServiceProvider (
		ServiceProviderID,
		ComputerID,
		ParentServiceProviderID,
		ServiceProviderTypeID,
		ServiceProviderNameID,
		LastInventoryDate,
		LastInventoryResult,
		LastInventoryError,
		CreationDate
	)
	VALUES (
		@ServiceProviderID,
		@ComputerID,
		@ParentServiceProviderID,
		@ServiceProviderTypeID,
		@ServiceProviderNameID,
		@LastInventoryDate,
		@LastInventoryResult,
		@LastInventoryError,
		@CreationDate
	)
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ServiceProviderAddBatch]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ServiceProviderAddBatch]
GO
CREATE PROCEDURE dbo.[ServiceProviderAddBatch]
AS
	DECLARE @count int
	INSERT dbo.ServiceProvider (
		ComputerID,
		ParentServiceProviderID,
		ServiceProviderTypeID,
		ServiceProviderNameID,
		LastInventoryDate,
		LastInventoryResult,
		LastInventoryError,
		CreationDate
	)
		SELECT	ComputerID,
			ParentServiceProviderID,
			ServiceProviderTypeID,
			ServiceProviderNameID,
			LastInventoryDate,
			LastInventoryResult,
			LastInventoryError,
			CreationDate
		FROM #ServiceProvider
	SET @count = @@ROWCOUNT
	DROP TABLE #ServiceProvider	-- Drop temporary table
	RETURN @count
GO

/*
Add new ServiceProvider bound to
	ServiceProviderType using Type
	ServiceProviderName using Name
	with ComputerID, ParentServiceProviderID, LastInventoryDate, LastInventoryResult, LastInventoryError, CreationDate
*/

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ServiceProviderUpdateByID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ServiceProviderUpdateByID]
GO
CREATE PROCEDURE [dbo].[ServiceProviderUpdateByID]
	@ServiceProviderID	int,
	@ComputerID		int,
	@ParentServiceProviderID int = NULL,
	@ServiceProviderTypeID	int,
	@ServiceProviderNameID	int,
	@LastInventoryDate	datetime,
	@LastInventoryResult	int = NULL,
	@LastInventoryError	nvarchar(256) = NULL,
	@CreationDate		datetime = NULL
AS
	DECLARE	@ID	int
	SET @ID = 0

	UPDATE	[dbo].[ServiceProvider]
	SET	@ID = ServiceProviderID,
		ComputerID = @ComputerID,
		ParentServiceProviderID = @ParentServiceProviderID,
		ServiceProviderTypeID = @ServiceProviderTypeID,
		ServiceProviderNameID = @ServiceProviderNameID,
		LastInventoryDate = @LastInventoryDate,
		LastInventoryResult = @LastInventoryResult,
		LastInventoryError = @LastInventoryError,
		CreationDate = @CreationDate
	WHERE	ServiceProviderID = @ServiceProviderID
	RETURN @ID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ServiceProviderUpdateBatchByID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ServiceProviderUpdateBatchByID]
GO
CREATE PROCEDURE dbo.[ServiceProviderUpdateBatchByID]
AS
	DECLARE @count int

	CREATE INDEX [TempServiceProviderID]
		ON #ServiceProvider (ServiceProviderID)

	UPDATE	[dbo].[ServiceProvider]
	SET	ComputerID = t.ComputerID,
		ParentServiceProviderID = t.ParentServiceProviderID,
		ServiceProviderTypeID = t.ServiceProviderTypeID,
		ServiceProviderNameID = t.ServiceProviderNameID,
		LastInventoryDate = t.LastInventoryDate,
		LastInventoryResult = t.LastInventoryResult,
		LastInventoryError = t.LastInventoryError,
		CreationDate = t.CreationDate
	FROM	#ServiceProvider AS t
	WHERE	ServiceProvider.ServiceProviderID = t.ServiceProviderID
	SET @count = @@ROWCOUNT
	DROP TABLE #ServiceProvider	-- Drop the temporary table
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ServiceProviderUpdateByComputerIDTypeIDNameID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ServiceProviderUpdateByComputerIDTypeIDNameID]
GO
CREATE PROCEDURE [dbo].[ServiceProviderUpdateByComputerIDTypeIDNameID]
	@ComputerID		int,
	@ServiceProviderTypeID	int,
	@ServiceProviderNameID	int,
	@ParentServiceProviderID int = NULL,
	@LastInventoryDate	datetime,
	@LastInventoryResult	int = NULL,
	@LastInventoryError	nvarchar(256) = NULL,
	@CreationDate		datetime = NULL
AS
	DECLARE	@ID	int
	SET @ID = 0

	UPDATE	[dbo].[ServiceProvider]
	SET	@ID = ServiceProviderID,
		ParentServiceProviderID = @ParentServiceProviderID,
		LastInventoryDate = @LastInventoryDate,
		LastInventoryResult = @LastInventoryResult,
		LastInventoryError = @LastInventoryError,
		CreationDate = @CreationDate
	WHERE	ComputerID = @ComputerID
	  AND	ServiceProviderTypeID = @ServiceProviderTypeID
	  AND	ServiceProviderNameID = @ServiceProviderNameID
	RETURN @ID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ServiceProviderUpdateBatchByComputerIDTypeIDNameID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ServiceProviderUpdateBatchByComputerIDTypeIDNameID]
GO
CREATE PROCEDURE dbo.[ServiceProviderUpdateBatchByComputerIDTypeIDNameID]
AS
	DECLARE @count int

	CREATE INDEX [TempServiceProviderComputerIDTypeIDNameID]
		ON #ServiceProvider (ComputerID, ServiceProviderTypeID, ServiceProviderNameID)

	UPDATE	[dbo].[ServiceProvider]
	SET	ParentServiceProviderID = t.ParentServiceProviderID,
		LastInventoryDate = t.LastInventoryDate,
		LastInventoryResult = t.LastInventoryResult,
		LastInventoryError = t.LastInventoryError,
		CreationDate = t.CreationDate
	FROM	#ServiceProvider AS t
	WHERE	ServiceProvider.ComputerID = t.ComputerID
	  AND	ServiceProvider.ServiceProviderTypeID = t.ServiceProviderTypeID
	  AND	ServiceProvider.ServiceProviderNameID = t.ServiceProviderNameID
	SET @count = @@ROWCOUNT
	DROP TABLE #ServiceProvider	-- Drop the temporary table
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ServiceProviderPutByComputerIDTypeIDNameID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ServiceProviderPutByComputerIDTypeIDNameID]
GO
CREATE PROCEDURE [dbo].[ServiceProviderPutByComputerIDTypeIDNameID]
	@ComputerID		int,
	@ServiceProviderTypeID	int,
	@ServiceProviderNameID	int,
	@ParentServiceProviderID int = NULL,
	@LastInventoryDate	datetime,
	@LastInventoryResult	int = NULL,
	@LastInventoryError	nvarchar(256) = NULL,
	@CreationDate		datetime = NULL
AS
	DECLARE @ID	int

	SELECT	@ID = ServiceProviderID
	FROM	ServiceProvider
	WHERE	ComputerID = @ComputerID
	  AND	ServiceProviderTypeID = @ServiceProviderTypeID
	  AND	ServiceProviderNameID = @ServiceProviderNameID

	IF @ID IS NULL
		EXEC @ID = ServiceProviderAdd @ComputerID,
			@ParentServiceProviderID,
			@ServiceProviderTypeID,
			@ServiceProviderNameID,
			@LastInventoryDate,
			@LastInventoryResult,
			@LastInventoryError,
			@CreationDate
	ELSE
		EXEC ServiceProviderUpdateByComputerIDTypeIDNameID @ComputerID,
			@ServiceProviderTypeID,
			@ServiceProviderNameID,
			@ParentServiceProviderID,
			@LastInventoryDate,
			@LastInventoryResult,
			@LastInventoryError,
			@CreationDate

	RETURN @ID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ServiceProviderPutBatchByComputerIDTypeIDNameID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ServiceProviderPutBatchByComputerIDTypeIDNameID]
GO
CREATE PROCEDURE [dbo].[ServiceProviderPutBatchByComputerIDTypeIDNameID]
AS
	DECLARE @count AS int
	SET @count = 0

	CREATE INDEX [TempServiceProviderComputerIDTypeIDNameID]
		ON #ServiceProvider (ComputerID, ServiceProviderTypeID, ServiceProviderNameID)

	BEGIN TRANSACTION
	UPDATE [dbo].[ServiceProvider]
		SET	ParentServiceProviderID = t.ParentServiceProviderID,
			LastInventoryDate = t.LastInventoryDate,
			LastInventoryResult = t.LastInventoryResult,
			LastInventoryError = t.LastInventoryError,
			CreationDate = t.CreationDate
		FROM	#ServiceProvider AS t
		WHERE	ServiceProvider.ComputerID = t.ComputerID
		  AND	ServiceProvider.ServiceProviderTypeID = t.ServiceProviderTypeID
		  AND	ServiceProvider.ServiceProviderNameID = t.ServiceProviderNameID
	SET @count = @@ROWCOUNT

	INSERT [dbo].[ServiceProvider] (
		ComputerID,
		ParentServiceProviderID,
		ServiceProviderTypeID,
		ServiceProviderNameID,
		LastInventoryDate,
		LastInventoryResult,
		LastInventoryError,
		CreationDate
	)
		SELECT	ComputerID,
			ParentServiceProviderID,
			ServiceProviderTypeID,
			ServiceProviderNameID,
			LastInventoryDate,
			LastInventoryResult,
			LastInventoryError,
			CreationDate
		FROM	#ServiceProvider AS t
		WHERE NOT EXISTS(	-- Current record doesn't exist
			SELECT * FROM [dbo].[ServiceProvider]
			WHERE	ServiceProvider.ComputerID = t.ComputerID
			  AND	ServiceProvider.ServiceProviderTypeID = t.ServiceProviderTypeID
			  AND	ServiceProvider.ServiceProviderNameID = t.ServiceProviderNameID
		)
	SET @count = @count + @@ROWCOUNT
	DROP TABLE #ServiceProvider	-- Drop the temporary table
	COMMIT WORK
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ServiceProviderRemoveBatch]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ServiceProviderRemoveBatch]
GO

CREATE PROCEDURE [dbo].[ServiceProviderRemoveBatch]
AS

	CREATE INDEX [TempServiceProviderServiceProviderRemoveBatch]
		ON #ServiceProvider (ServiceProviderID)	

	-- Delete records from ServiceProvider identified by fields of [TempServiceProviderServiceProviderRemoveBatch]
	DELETE [dbo].[ServiceProvider]
	WHERE EXISTS(
			SELECT * FROM #ServiceProvider AS t
			WHERE	ServiceProvider.ServiceProviderID = t.ServiceProviderID
		)
	DROP TABLE #ServiceProvider      -- Drop the temporary table
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ServiceProviderRemoveByComputerIDTypeIDNameID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ServiceProviderRemoveByComputerIDTypeIDNameID]
GO
CREATE PROCEDURE [dbo].[ServiceProviderRemoveByComputerIDTypeIDNameID]
	@ComputerID		int,
	@ServiceProviderTypeID	int,
	@ServiceProviderNameID	int
AS
	-- ServiceProvider deletes cascade to:
	--	ServiceProviderValue by FK_ServiceProviderValue_ServiceProvider
	--	ServiceProviderComponent by FK_ServiceProviderComponent_ServiceProvider
	--	ServiceProviderComponentValue by FK_ServiceProviderComponentValue_ServiceProvider
	--	ServiceUser by FK_ServiceUser_ServiceProvider
	--		ServiceUserOracle by FK_ServiceUserOracle_ServiceUser
	--	ServiceProviderApplicationOracle by FK_ServiceProviderApplicationOracle_ServiceProvider
	--		ServiceProviderApplicationUserOracle by FK_ServiceProviderApplicationUserOracle_Application
	-- ServiceProvider deletes may fail due to non-cascading FKs:
	--	ServiceProvider by FK_ServiceProvider_Parent
	DELETE	[dbo].[ServiceProvider]
	WHERE	ComputerID = @ComputerID
	  AND	ServiceProviderTypeID = @ServiceProviderTypeID
	  AND	ServiceProviderNameID = @ServiceProviderNameID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ServiceProviderRemoveAllByComputerID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ServiceProviderRemoveAllByComputerID]
GO
CREATE PROCEDURE [dbo].[ServiceProviderRemoveAllByComputerID]
	@ComputerID		int
AS
	DELETE	[dbo].[ServiceProvider]
	WHERE	ComputerID = @ComputerID
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ServiceProviderRemoveAll]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ServiceProviderRemoveAll]
GO
CREATE PROCEDURE [dbo].[ServiceProviderRemoveAll]
	
AS
	DELETE	[dbo].[ServiceProvider]
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ServiceProviderReplaceSubsetByComputerID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ServiceProviderReplaceSubsetByComputerID]
GO
-- Replace the record subset selected by (@ComputerID)
-- using unique identifier (ComputerID, ServiceProviderTypeID, ServiceProviderNameID)
-- updating fields (ParentServiceProviderID, LastInventoryDate, LastInventoryResult, LastInventoryError, CreationDate)
CREATE PROCEDURE [dbo].[ServiceProviderReplaceSubsetByComputerID]
	@ComputerID		int
AS
	DECLARE @count AS int
	SET @count = 0

	CREATE INDEX [TempServiceProviderByComputerID]
		ON #ServiceProvider (ComputerID, ServiceProviderTypeID, ServiceProviderNameID)

	BEGIN TRANSACTION
	DELETE [ServiceProvider]
		WHERE	ComputerID = @ComputerID
		AND NOT EXISTS(		-- Replacement record doesn't exist
			SELECT * FROM #ServiceProvider AS t
			WHERE	ServiceProvider.ComputerID = t.ComputerID
			  AND	ServiceProvider.ServiceProviderTypeID = t.ServiceProviderTypeID
			  AND	ServiceProvider.ServiceProviderNameID = t.ServiceProviderNameID
		)

	UPDATE [dbo].[ServiceProvider]
		SET	ParentServiceProviderID = t.ParentServiceProviderID,
			LastInventoryDate = t.LastInventoryDate,
			LastInventoryResult = t.LastInventoryResult,
			LastInventoryError = t.LastInventoryError,
			CreationDate = t.CreationDate
		FROM	#ServiceProvider AS t
		WHERE	ServiceProvider.ComputerID = t.ComputerID
		  AND	ServiceProvider.ServiceProviderTypeID = t.ServiceProviderTypeID
		  AND	ServiceProvider.ServiceProviderNameID = t.ServiceProviderNameID
	SET @count = @@ROWCOUNT

	INSERT [ServiceProvider] (
		ComputerID,
		ParentServiceProviderID,
		ServiceProviderTypeID,
		ServiceProviderNameID,
		LastInventoryDate,
		LastInventoryResult,
		LastInventoryError,
		CreationDate
	)
		SELECT	ComputerID,
			ParentServiceProviderID,
			ServiceProviderTypeID,
			ServiceProviderNameID,
			LastInventoryDate,
			LastInventoryResult,
			LastInventoryError,
			CreationDate
		FROM	#ServiceProvider AS t
		WHERE NOT EXISTS(	-- Current record doesn't exist
			SELECT * FROM [ServiceProvider]
			WHERE	ServiceProvider.ComputerID = t.ComputerID
			  AND	ServiceProvider.ServiceProviderTypeID = t.ServiceProviderTypeID
			  AND	ServiceProvider.ServiceProviderNameID = t.ServiceProviderNameID
		)
	SET @count = @count + @@ROWCOUNT
	DROP TABLE #ServiceProvider	-- Drop the temporary table
	COMMIT WORK
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ServiceProviderPropertyGetByProperty]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ServiceProviderPropertyGetByProperty]
GO
CREATE PROCEDURE [dbo].[ServiceProviderPropertyGetByProperty]
	@Property		nvarchar(256)
AS
	SELECT	ServiceProviderPropertyID,
		Property
	FROM	[dbo].[ServiceProviderProperty]
	WHERE	Property = @Property
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ServiceProviderPropertyGetByID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ServiceProviderPropertyGetByID]
GO
CREATE PROCEDURE [dbo].[ServiceProviderPropertyGetByID]
	@ServiceProviderPropertyID int
AS
	SELECT	ServiceProviderPropertyID,
		Property
	FROM	[dbo].[ServiceProviderProperty]
	WHERE	ServiceProviderPropertyID = @ServiceProviderPropertyID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ServiceProviderPropertyGetAll]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ServiceProviderPropertyGetAll]
GO
CREATE PROCEDURE [dbo].[ServiceProviderPropertyGetAll]
AS
	SELECT	ServiceProviderPropertyID,
		Property
	FROM	[dbo].[ServiceProviderProperty]
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ServiceProviderPropertyAdd]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ServiceProviderPropertyAdd]
GO
CREATE PROCEDURE [dbo].[ServiceProviderPropertyAdd]
	@Property		nvarchar(256)
AS
	INSERT INTO  dbo.ServiceProviderProperty (
		Property
	)
	VALUES (
		@Property
	)
	RETURN SCOPE_IDENTITY()
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ServiceProviderPropertyBind]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ServiceProviderPropertyBind]
GO
CREATE PROCEDURE [dbo].[ServiceProviderPropertyBind]
	@Property		nvarchar(256)
AS
	DECLARE	@ID	int

	SELECT	@ID = ServiceProviderPropertyID
	FROM	[dbo].[ServiceProviderProperty]
	WHERE	Property = @Property

	IF @ID IS NULL
		EXEC @ID = ServiceProviderPropertyAdd @Property

	RETURN @ID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ServiceProviderPropertySchema]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ServiceProviderPropertySchema]
GO
CREATE PROCEDURE [dbo].[ServiceProviderPropertySchema]
AS
	SELECT
	'IF OBJECT_ID(''tempdb..#ServiceProviderProperty'') IS NULL' + CAST(0x0A AS CHAR(1)) +
	'	CREATE TABLE #ServiceProviderProperty (' + CAST(0x0A AS CHAR(1)) +
	'		ServiceProviderPropertyID int NULL,' + CAST(0x0A AS CHAR(1)) +
	'		Property		nvarchar(256) COLLATE database_default NOT NULL' + CAST(0x0A AS CHAR(1)) +
	'	)' + CAST(0x0A AS CHAR(1)) +
	'ELSE' + CAST(0x0A AS CHAR(1)) +
	'	DELETE FROM #ServiceProviderProperty' + CAST(0x0A AS CHAR(1)) +
	'' AS SQL
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ServiceProviderPropertyTempAdd]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ServiceProviderPropertyTempAdd]
GO
CREATE PROCEDURE dbo.[ServiceProviderPropertyTempAdd]
	@ServiceProviderPropertyID int,
	@Property		nvarchar(256)
AS
	INSERT INTO #ServiceProviderProperty (
		ServiceProviderPropertyID,
		Property
	)
	VALUES (
		@ServiceProviderPropertyID,
		@Property
	)
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ServiceProviderPropertyAddBatch]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ServiceProviderPropertyAddBatch]
GO
CREATE PROCEDURE dbo.[ServiceProviderPropertyAddBatch]
AS
	DECLARE @count int
	INSERT dbo.ServiceProviderProperty (
		Property
	)
		SELECT	Property
		FROM #ServiceProviderProperty
	SET @count = @@ROWCOUNT
	DROP TABLE #ServiceProviderProperty	-- Drop temporary table
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ServiceProviderPropertyUpdateByID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ServiceProviderPropertyUpdateByID]
GO
CREATE PROCEDURE [dbo].[ServiceProviderPropertyUpdateByID]
	@ServiceProviderPropertyID int,
	@Property		nvarchar(256)
AS
	DECLARE	@ID	int
	SET @ID = 0

	UPDATE	[dbo].[ServiceProviderProperty]
	SET	@ID = ServiceProviderPropertyID,
		Property = @Property
	WHERE	ServiceProviderPropertyID = @ServiceProviderPropertyID
	RETURN @ID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ServiceProviderPropertyUpdateBatchByID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ServiceProviderPropertyUpdateBatchByID]
GO
CREATE PROCEDURE dbo.[ServiceProviderPropertyUpdateBatchByID]
AS
	DECLARE @count int

	CREATE INDEX [TempServiceProviderPropertyID]
		ON #ServiceProviderProperty (ServiceProviderPropertyID)

	UPDATE	[dbo].[ServiceProviderProperty]
	SET	Property = t.Property
	FROM	#ServiceProviderProperty AS t
	WHERE	ServiceProviderProperty.ServiceProviderPropertyID = t.ServiceProviderPropertyID
	SET @count = @@ROWCOUNT
	DROP TABLE #ServiceProviderProperty	-- Drop the temporary table
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ServiceProviderPropertyPutByProperty]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ServiceProviderPropertyPutByProperty]
GO
CREATE PROCEDURE [dbo].[ServiceProviderPropertyPutByProperty]
	@Property		nvarchar(256)
AS
	DECLARE @ID	int

	SELECT	@ID = ServiceProviderPropertyID
	FROM	ServiceProviderProperty
	WHERE	Property = @Property

	IF @ID IS NULL
		EXEC @ID = ServiceProviderPropertyAdd @Property

	RETURN @ID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ServiceProviderPropertyPutBatchByProperty]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ServiceProviderPropertyPutBatchByProperty]
GO
CREATE PROCEDURE [dbo].[ServiceProviderPropertyPutBatchByProperty]
AS
	DECLARE @count AS int
	SET @count = 0

	CREATE INDEX [TempServiceProviderPropertyProperty]
		ON #ServiceProviderProperty (Property)

	BEGIN TRANSACTION

	INSERT [dbo].[ServiceProviderProperty] (
		Property
	)
		SELECT	Property
		FROM	#ServiceProviderProperty AS t
		WHERE NOT EXISTS(	-- Current record doesn't exist
			SELECT * FROM [dbo].[ServiceProviderProperty]
			WHERE	ServiceProviderProperty.Property = t.Property
		)
	SET @count = @count + @@ROWCOUNT
	DROP TABLE #ServiceProviderProperty	-- Drop the temporary table
	COMMIT WORK
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ServiceProviderPropertyRemoveBatch]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ServiceProviderPropertyRemoveBatch]
GO

CREATE PROCEDURE [dbo].[ServiceProviderPropertyRemoveBatch]
AS

	CREATE INDEX [TempServiceProviderPropertyServiceProviderPropertyRemoveBatch]
		ON #ServiceProviderProperty (ServiceProviderPropertyID)	

	-- Delete records from ServiceProviderProperty identified by fields of [TempServiceProviderPropertyServiceProviderPropertyRemoveBatch]
	DELETE [dbo].[ServiceProviderProperty]
	WHERE EXISTS(
			SELECT * FROM #ServiceProviderProperty AS t
			WHERE	ServiceProviderProperty.ServiceProviderPropertyID = t.ServiceProviderPropertyID
		)
	DROP TABLE #ServiceProviderProperty      -- Drop the temporary table
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ServiceProviderPropertyRemoveByProperty]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ServiceProviderPropertyRemoveByProperty]
GO
CREATE PROCEDURE [dbo].[ServiceProviderPropertyRemoveByProperty]
	@Property		nvarchar(256)
AS
	-- ServiceProviderProperty deletes cascade to:
	--	ServiceProviderValue by FK_ServiceProviderValue_ServiceProviderProperty
	DELETE	[dbo].[ServiceProviderProperty]
	WHERE	Property = @Property
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ServiceProviderPropertyRemoveAll]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ServiceProviderPropertyRemoveAll]
GO
CREATE PROCEDURE [dbo].[ServiceProviderPropertyRemoveAll]
	
AS
	DELETE	[dbo].[ServiceProviderProperty]
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ServiceProviderValueGetByServiceProviderIDServiceProviderPropertyID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ServiceProviderValueGetByServiceProviderIDServiceProviderPropertyID]
GO
CREATE PROCEDURE [dbo].[ServiceProviderValueGetByServiceProviderIDServiceProviderPropertyID]
	@ServiceProviderID	int,
	@ServiceProviderPropertyID int
AS
	SELECT	ServiceProviderID,
		ServiceProviderPropertyID,
		Value
	FROM	[dbo].[ServiceProviderValue]
	WHERE	ServiceProviderID = @ServiceProviderID
	  AND	ServiceProviderPropertyID = @ServiceProviderPropertyID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ServiceProviderValueGetAllByServiceProviderID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ServiceProviderValueGetAllByServiceProviderID]
GO
CREATE PROCEDURE [dbo].[ServiceProviderValueGetAllByServiceProviderID]
	@ServiceProviderID	int
AS
	SELECT	ServiceProviderID,
		ServiceProviderPropertyID,
		Value
	FROM	[dbo].[ServiceProviderValue]
	WHERE	ServiceProviderID = @ServiceProviderID
	ORDER BY ServiceProviderPropertyID
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ServiceProviderValueGetAll]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ServiceProviderValueGetAll]
GO
CREATE PROCEDURE [dbo].[ServiceProviderValueGetAll]
AS
	SELECT	ServiceProviderID,
		ServiceProviderPropertyID,
		Value
	FROM	[dbo].[ServiceProviderValue]
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ServiceProviderValueAdd]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ServiceProviderValueAdd]
GO
CREATE PROCEDURE [dbo].[ServiceProviderValueAdd]
	@ServiceProviderID	int,
	@ServiceProviderPropertyID int,
	@Value			nvarchar(256) = NULL
AS
	INSERT INTO  dbo.ServiceProviderValue (
		ServiceProviderID,
		ServiceProviderPropertyID,
		Value
	)
	VALUES (
		@ServiceProviderID,
		@ServiceProviderPropertyID,
		@Value
	)
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ServiceProviderValueSchema]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ServiceProviderValueSchema]
GO
CREATE PROCEDURE [dbo].[ServiceProviderValueSchema]
AS
	SELECT
	'IF OBJECT_ID(''tempdb..#ServiceProviderValue'') IS NULL' + CAST(0x0A AS CHAR(1)) +
	'	CREATE TABLE #ServiceProviderValue (' + CAST(0x0A AS CHAR(1)) +
	'		ServiceProviderID	int NOT NULL,' + CAST(0x0A AS CHAR(1)) +
	'		ServiceProviderPropertyID int NOT NULL,' + CAST(0x0A AS CHAR(1)) +
	'		Value			nvarchar(256) COLLATE database_default NULL' + CAST(0x0A AS CHAR(1)) +
	'	)' + CAST(0x0A AS CHAR(1)) +
	'ELSE' + CAST(0x0A AS CHAR(1)) +
	'	DELETE FROM #ServiceProviderValue' + CAST(0x0A AS CHAR(1)) +
	'' AS SQL
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ServiceProviderValueTempAdd]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ServiceProviderValueTempAdd]
GO
CREATE PROCEDURE dbo.[ServiceProviderValueTempAdd]
	@ServiceProviderID	int,
	@ServiceProviderPropertyID int,
	@Value			nvarchar(256) = NULL
AS
	INSERT INTO #ServiceProviderValue (
		ServiceProviderID,
		ServiceProviderPropertyID,
		Value
	)
	VALUES (
		@ServiceProviderID,
		@ServiceProviderPropertyID,
		@Value
	)
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ServiceProviderValueAddBatch]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ServiceProviderValueAddBatch]
GO
CREATE PROCEDURE dbo.[ServiceProviderValueAddBatch]
AS
	DECLARE @count int
	INSERT dbo.ServiceProviderValue (
		ServiceProviderID,
		ServiceProviderPropertyID,
		Value
	)
		SELECT	ServiceProviderID,
			ServiceProviderPropertyID,
			Value
		FROM #ServiceProviderValue
	SET @count = @@ROWCOUNT
	DROP TABLE #ServiceProviderValue	-- Drop temporary table
	RETURN @count
GO

/*
Add new ServiceProviderValue bound to
	ServiceProviderProperty using Property
	with ServiceProviderID, Value
*/

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ServiceProviderValueUpdateByServiceProviderIDServiceProviderPropertyID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ServiceProviderValueUpdateByServiceProviderIDServiceProviderPropertyID]
GO
CREATE PROCEDURE [dbo].[ServiceProviderValueUpdateByServiceProviderIDServiceProviderPropertyID]
	@ServiceProviderID	int,
	@ServiceProviderPropertyID int,
	@Value			nvarchar(256) = NULL
AS
	UPDATE	[dbo].[ServiceProviderValue]
	SET	Value = @Value
	WHERE	ServiceProviderID = @ServiceProviderID
	  AND	ServiceProviderPropertyID = @ServiceProviderPropertyID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ServiceProviderValueUpdateBatchByServiceProviderIDServiceProviderPropertyID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ServiceProviderValueUpdateBatchByServiceProviderIDServiceProviderPropertyID]
GO
CREATE PROCEDURE dbo.[ServiceProviderValueUpdateBatchByServiceProviderIDServiceProviderPropertyID]
AS
	DECLARE @count int

	CREATE INDEX [TempServiceProviderValueServiceProviderIDServiceProviderPropertyID]
		ON #ServiceProviderValue (ServiceProviderID, ServiceProviderPropertyID)

	UPDATE	[dbo].[ServiceProviderValue]
	SET	Value = t.Value
	FROM	#ServiceProviderValue AS t
	WHERE	ServiceProviderValue.ServiceProviderID = t.ServiceProviderID
	  AND	ServiceProviderValue.ServiceProviderPropertyID = t.ServiceProviderPropertyID
	SET @count = @@ROWCOUNT
	DROP TABLE #ServiceProviderValue	-- Drop the temporary table
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ServiceProviderValuePutByServiceProviderIDServiceProviderPropertyID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ServiceProviderValuePutByServiceProviderIDServiceProviderPropertyID]
GO
CREATE PROCEDURE [dbo].[ServiceProviderValuePutByServiceProviderIDServiceProviderPropertyID]
	@ServiceProviderID	int,
	@ServiceProviderPropertyID int,
	@Value			nvarchar(256) = NULL
AS
	IF NOT EXISTS(
		SELECT	1
		FROM	dbo.ServiceProviderValue
		WHERE	ServiceProviderID = @ServiceProviderID
		  AND	ServiceProviderPropertyID = @ServiceProviderPropertyID
	)
		EXEC ServiceProviderValueAdd @ServiceProviderID,
			@ServiceProviderPropertyID,
			@Value
	ELSE
		EXEC ServiceProviderValueUpdateByServiceProviderIDServiceProviderPropertyID @ServiceProviderID,
			@ServiceProviderPropertyID,
			@Value
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ServiceProviderValuePutBatchByServiceProviderIDServiceProviderPropertyID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ServiceProviderValuePutBatchByServiceProviderIDServiceProviderPropertyID]
GO
CREATE PROCEDURE [dbo].[ServiceProviderValuePutBatchByServiceProviderIDServiceProviderPropertyID]
AS
	DECLARE @count AS int
	SET @count = 0

	CREATE INDEX [TempServiceProviderValueServiceProviderIDServiceProviderPropertyID]
		ON #ServiceProviderValue (ServiceProviderID, ServiceProviderPropertyID)

	BEGIN TRANSACTION
	UPDATE [dbo].[ServiceProviderValue]
		SET	Value = t.Value
		FROM	#ServiceProviderValue AS t
		WHERE	ServiceProviderValue.ServiceProviderID = t.ServiceProviderID
		  AND	ServiceProviderValue.ServiceProviderPropertyID = t.ServiceProviderPropertyID
	SET @count = @@ROWCOUNT

	INSERT [dbo].[ServiceProviderValue] (
		ServiceProviderID,
		ServiceProviderPropertyID,
		Value
	)
		SELECT	ServiceProviderID,
			ServiceProviderPropertyID,
			Value
		FROM	#ServiceProviderValue AS t
		WHERE NOT EXISTS(	-- Current record doesn't exist
			SELECT * FROM [dbo].[ServiceProviderValue]
			WHERE	ServiceProviderValue.ServiceProviderID = t.ServiceProviderID
			  AND	ServiceProviderValue.ServiceProviderPropertyID = t.ServiceProviderPropertyID
		)
	SET @count = @count + @@ROWCOUNT
	DROP TABLE #ServiceProviderValue	-- Drop the temporary table
	COMMIT WORK
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ServiceProviderValueRemoveBatch]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ServiceProviderValueRemoveBatch]
GO

CREATE PROCEDURE [dbo].[ServiceProviderValueRemoveBatch]
AS

	CREATE INDEX [TempServiceProviderValueServiceProviderValueRemoveBatch]
		ON #ServiceProviderValue (ServiceProviderID, ServiceProviderPropertyID)	

	-- Delete records from ServiceProviderValue identified by fields of [TempServiceProviderValueServiceProviderValueRemoveBatch]
	DELETE [dbo].[ServiceProviderValue]
	WHERE EXISTS(
			SELECT * FROM #ServiceProviderValue AS t
			WHERE	ServiceProviderValue.ServiceProviderID = t.ServiceProviderID
			  AND	ServiceProviderValue.ServiceProviderPropertyID = t.ServiceProviderPropertyID
		)
	DROP TABLE #ServiceProviderValue      -- Drop the temporary table
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ServiceProviderValueRemoveByServiceProviderIDServiceProviderPropertyID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ServiceProviderValueRemoveByServiceProviderIDServiceProviderPropertyID]
GO
CREATE PROCEDURE [dbo].[ServiceProviderValueRemoveByServiceProviderIDServiceProviderPropertyID]
	@ServiceProviderID	int,
	@ServiceProviderPropertyID int
AS
	DELETE	[dbo].[ServiceProviderValue]
	WHERE	ServiceProviderID = @ServiceProviderID
	  AND	ServiceProviderPropertyID = @ServiceProviderPropertyID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ServiceProviderValueRemoveAllByServiceProviderID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ServiceProviderValueRemoveAllByServiceProviderID]
GO
CREATE PROCEDURE [dbo].[ServiceProviderValueRemoveAllByServiceProviderID]
	@ServiceProviderID	int
AS
	DELETE	[dbo].[ServiceProviderValue]
	WHERE	ServiceProviderID = @ServiceProviderID
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ServiceProviderValueRemoveAll]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ServiceProviderValueRemoveAll]
GO
CREATE PROCEDURE [dbo].[ServiceProviderValueRemoveAll]
	
AS
	DELETE	[dbo].[ServiceProviderValue]
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ServiceProviderValueReplaceSubsetByServiceProviderID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ServiceProviderValueReplaceSubsetByServiceProviderID]
GO
-- Replace the record subset selected by (@ServiceProviderID)
-- using unique identifier (ServiceProviderID, ServiceProviderPropertyID)
-- updating fields (Value)
CREATE PROCEDURE [dbo].[ServiceProviderValueReplaceSubsetByServiceProviderID]
	@ServiceProviderID	int
AS
	DECLARE @count AS int
	SET @count = 0

	CREATE INDEX [TempServiceProviderValueByServiceProviderID]
		ON #ServiceProviderValue (ServiceProviderID, ServiceProviderPropertyID)

	BEGIN TRANSACTION
	DELETE [ServiceProviderValue]
		WHERE	ServiceProviderID = @ServiceProviderID
		AND NOT EXISTS(		-- Replacement record doesn't exist
			SELECT * FROM #ServiceProviderValue AS t
			WHERE	ServiceProviderValue.ServiceProviderID = t.ServiceProviderID
			  AND	ServiceProviderValue.ServiceProviderPropertyID = t.ServiceProviderPropertyID
		)

	UPDATE [dbo].[ServiceProviderValue]
		SET	Value = t.Value
		FROM	#ServiceProviderValue AS t
		WHERE	ServiceProviderValue.ServiceProviderID = t.ServiceProviderID
		  AND	ServiceProviderValue.ServiceProviderPropertyID = t.ServiceProviderPropertyID
	SET @count = @@ROWCOUNT

	INSERT [ServiceProviderValue] (
		ServiceProviderID,
		ServiceProviderPropertyID,
		Value
	)
		SELECT	ServiceProviderID,
			ServiceProviderPropertyID,
			Value
		FROM	#ServiceProviderValue AS t
		WHERE NOT EXISTS(	-- Current record doesn't exist
			SELECT * FROM [ServiceProviderValue]
			WHERE	ServiceProviderValue.ServiceProviderID = t.ServiceProviderID
			  AND	ServiceProviderValue.ServiceProviderPropertyID = t.ServiceProviderPropertyID
		)
	SET @count = @count + @@ROWCOUNT
	DROP TABLE #ServiceProviderValue	-- Drop the temporary table
	COMMIT WORK
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ServiceComponentGetByNameVersionPublisherEdition]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ServiceComponentGetByNameVersionPublisherEdition]
GO
CREATE PROCEDURE [dbo].[ServiceComponentGetByNameVersionPublisherEdition]
	@Name			nvarchar(128),
	@Version		nvarchar(32),
	@Publisher		nvarchar(128),
	@Edition		nvarchar(128)
AS
	SELECT	ServiceComponentID,
		[Name],
		Version,
		Publisher,
		Edition
	FROM	[dbo].[ServiceComponent]
	WHERE	[Name] = @Name
	  AND	Version = @Version
	  AND	Publisher = @Publisher
	  AND	Edition = @Edition
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ServiceComponentGetByID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ServiceComponentGetByID]
GO
CREATE PROCEDURE [dbo].[ServiceComponentGetByID]
	@ServiceComponentID	int
AS
	SELECT	ServiceComponentID,
		[Name],
		Version,
		Publisher,
		Edition
	FROM	[dbo].[ServiceComponent]
	WHERE	ServiceComponentID = @ServiceComponentID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ServiceComponentGetAll]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ServiceComponentGetAll]
GO
CREATE PROCEDURE [dbo].[ServiceComponentGetAll]
AS
	SELECT	ServiceComponentID,
		[Name],
		Version,
		Publisher,
		Edition
	FROM	[dbo].[ServiceComponent]
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ServiceComponentAdd]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ServiceComponentAdd]
GO
CREATE PROCEDURE [dbo].[ServiceComponentAdd]
	@Name			nvarchar(128),
	@Version		nvarchar(32),
	@Publisher		nvarchar(128),
	@Edition		nvarchar(128)
AS
	INSERT INTO  dbo.ServiceComponent (
		[Name],
		Version,
		Publisher,
		Edition
	)
	VALUES (
		@Name,
		@Version,
		@Publisher,
		@Edition
	)
	RETURN SCOPE_IDENTITY()
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ServiceComponentBind]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ServiceComponentBind]
GO
CREATE PROCEDURE [dbo].[ServiceComponentBind]
	@Name			nvarchar(128),
	@Version		nvarchar(32),
	@Publisher		nvarchar(128),
	@Edition		nvarchar(128)
AS
	DECLARE	@ID	int

	SELECT	@ID = ServiceComponentID
	FROM	[dbo].[ServiceComponent]
	WHERE	[Name] = @Name
	  AND	Version = @Version
	  AND	Publisher = @Publisher
	  AND	Edition = @Edition

	IF @ID IS NULL
		EXEC @ID = ServiceComponentAdd @Name,
			@Version,
			@Publisher,
			@Edition

	RETURN @ID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ServiceComponentSchema]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ServiceComponentSchema]
GO
CREATE PROCEDURE [dbo].[ServiceComponentSchema]
AS
	SELECT
	'IF OBJECT_ID(''tempdb..#ServiceComponent'') IS NULL' + CAST(0x0A AS CHAR(1)) +
	'	CREATE TABLE #ServiceComponent (' + CAST(0x0A AS CHAR(1)) +
	'		ServiceComponentID	int NULL,' + CAST(0x0A AS CHAR(1)) +
	'		[Name]			nvarchar(128) COLLATE database_default NOT NULL,' + CAST(0x0A AS CHAR(1)) +
	'		Version			nvarchar(32) COLLATE database_default NOT NULL,' + CAST(0x0A AS CHAR(1)) +
	'		Publisher		nvarchar(128) COLLATE database_default NOT NULL,' + CAST(0x0A AS CHAR(1)) +
	'		Edition			nvarchar(128) COLLATE database_default NOT NULL' + CAST(0x0A AS CHAR(1)) +
	'	)' + CAST(0x0A AS CHAR(1)) +
	'ELSE' + CAST(0x0A AS CHAR(1)) +
	'	DELETE FROM #ServiceComponent' + CAST(0x0A AS CHAR(1)) +
	'' AS SQL
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ServiceComponentTempAdd]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ServiceComponentTempAdd]
GO
CREATE PROCEDURE dbo.[ServiceComponentTempAdd]
	@ServiceComponentID	int,
	@Name			nvarchar(128),
	@Version		nvarchar(32),
	@Publisher		nvarchar(128),
	@Edition		nvarchar(128)
AS
	INSERT INTO #ServiceComponent (
		ServiceComponentID,
		[Name],
		Version,
		Publisher,
		Edition
	)
	VALUES (
		@ServiceComponentID,
		@Name,
		@Version,
		@Publisher,
		@Edition
	)
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ServiceComponentAddBatch]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ServiceComponentAddBatch]
GO
CREATE PROCEDURE dbo.[ServiceComponentAddBatch]
AS
	DECLARE @count int
	INSERT dbo.ServiceComponent (
		[Name],
		Version,
		Publisher,
		Edition
	)
		SELECT	[Name],
			Version,
			Publisher,
			Edition
		FROM #ServiceComponent
	SET @count = @@ROWCOUNT
	DROP TABLE #ServiceComponent	-- Drop temporary table
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ServiceComponentUpdateByID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ServiceComponentUpdateByID]
GO
CREATE PROCEDURE [dbo].[ServiceComponentUpdateByID]
	@ServiceComponentID	int,
	@Name			nvarchar(128),
	@Version		nvarchar(32),
	@Publisher		nvarchar(128),
	@Edition		nvarchar(128)
AS
	DECLARE	@ID	int
	SET @ID = 0

	UPDATE	[dbo].[ServiceComponent]
	SET	@ID = ServiceComponentID,
		[Name] = @Name,
		Version = @Version,
		Publisher = @Publisher,
		Edition = @Edition
	WHERE	ServiceComponentID = @ServiceComponentID
	RETURN @ID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ServiceComponentUpdateBatchByID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ServiceComponentUpdateBatchByID]
GO
CREATE PROCEDURE dbo.[ServiceComponentUpdateBatchByID]
AS
	DECLARE @count int

	CREATE INDEX [TempServiceComponentID]
		ON #ServiceComponent (ServiceComponentID)

	UPDATE	[dbo].[ServiceComponent]
	SET	[Name] = t.[Name],
		Version = t.Version,
		Publisher = t.Publisher,
		Edition = t.Edition
	FROM	#ServiceComponent AS t
	WHERE	ServiceComponent.ServiceComponentID = t.ServiceComponentID
	SET @count = @@ROWCOUNT
	DROP TABLE #ServiceComponent	-- Drop the temporary table
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ServiceComponentPutByNameVersionPublisherEdition]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ServiceComponentPutByNameVersionPublisherEdition]
GO
CREATE PROCEDURE [dbo].[ServiceComponentPutByNameVersionPublisherEdition]
	@Name			nvarchar(128),
	@Version		nvarchar(32),
	@Publisher		nvarchar(128),
	@Edition		nvarchar(128)
AS
	DECLARE @ID	int

	SELECT	@ID = ServiceComponentID
	FROM	ServiceComponent
	WHERE	[Name] = @Name
	  AND	Version = @Version
	  AND	Publisher = @Publisher
	  AND	Edition = @Edition

	IF @ID IS NULL
		EXEC @ID = ServiceComponentAdd @Name,
			@Version,
			@Publisher,
			@Edition

	RETURN @ID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ServiceComponentPutBatchByNameVersionPublisherEdition]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ServiceComponentPutBatchByNameVersionPublisherEdition]
GO
CREATE PROCEDURE [dbo].[ServiceComponentPutBatchByNameVersionPublisherEdition]
AS
	DECLARE @count AS int
	SET @count = 0

	CREATE INDEX [TempServiceComponentNameVersionPublisherEdition]
		ON #ServiceComponent ([Name], Version, Publisher, Edition)

	BEGIN TRANSACTION

	INSERT [dbo].[ServiceComponent] (
		[Name],
		Version,
		Publisher,
		Edition
	)
		SELECT	[Name],
			Version,
			Publisher,
			Edition
		FROM	#ServiceComponent AS t
		WHERE NOT EXISTS(	-- Current record doesn't exist
			SELECT * FROM [dbo].[ServiceComponent]
			WHERE	ServiceComponent.[Name] = t.[Name]
			  AND	ServiceComponent.Version = t.Version
			  AND	ServiceComponent.Publisher = t.Publisher
			  AND	ServiceComponent.Edition = t.Edition
		)
	SET @count = @count + @@ROWCOUNT
	DROP TABLE #ServiceComponent	-- Drop the temporary table
	COMMIT WORK
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ServiceComponentRemoveBatch]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ServiceComponentRemoveBatch]
GO

CREATE PROCEDURE [dbo].[ServiceComponentRemoveBatch]
AS

	CREATE INDEX [TempServiceComponentServiceComponentRemoveBatch]
		ON #ServiceComponent (ServiceComponentID)	

	-- Delete records from ServiceComponent identified by fields of [TempServiceComponentServiceComponentRemoveBatch]
	DELETE [dbo].[ServiceComponent]
	WHERE EXISTS(
			SELECT * FROM #ServiceComponent AS t
			WHERE	ServiceComponent.ServiceComponentID = t.ServiceComponentID
		)
	DROP TABLE #ServiceComponent      -- Drop the temporary table
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ServiceComponentRemoveByNameVersionPublisherEdition]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ServiceComponentRemoveByNameVersionPublisherEdition]
GO
CREATE PROCEDURE [dbo].[ServiceComponentRemoveByNameVersionPublisherEdition]
	@Name			nvarchar(128),
	@Version		nvarchar(32),
	@Publisher		nvarchar(128),
	@Edition		nvarchar(128)
AS
	-- ServiceComponent deletes cascade to:
	--	ServiceProviderComponent by FK_ServiceProviderComponent_ServiceComponent
	--	ServiceProviderComponentValue by FK_ServiceProviderComponentValue_ServiceComponent
	DELETE	[dbo].[ServiceComponent]
	WHERE	[Name] = @Name
	  AND	Version = @Version
	  AND	Publisher = @Publisher
	  AND	Edition = @Edition
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ServiceComponentRemoveAll]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ServiceComponentRemoveAll]
GO
CREATE PROCEDURE [dbo].[ServiceComponentRemoveAll]
	
AS
	DELETE	[dbo].[ServiceComponent]
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ServiceProviderComponentGetByServiceProviderIDServiceComponentID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ServiceProviderComponentGetByServiceProviderIDServiceComponentID]
GO
CREATE PROCEDURE [dbo].[ServiceProviderComponentGetByServiceProviderIDServiceComponentID]
	@ServiceProviderID	int,
	@ServiceComponentID	int
AS
	SELECT	ServiceProviderID,
		ServiceComponentID
	FROM	[dbo].[ServiceProviderComponent]
	WHERE	ServiceProviderID = @ServiceProviderID
	  AND	ServiceComponentID = @ServiceComponentID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ServiceProviderComponentGetAllByServiceProviderID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ServiceProviderComponentGetAllByServiceProviderID]
GO
CREATE PROCEDURE [dbo].[ServiceProviderComponentGetAllByServiceProviderID]
	@ServiceProviderID	int
AS
	SELECT	ServiceProviderID,
		ServiceComponentID
	FROM	[dbo].[ServiceProviderComponent]
	WHERE	ServiceProviderID = @ServiceProviderID
	ORDER BY ServiceComponentID
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ServiceProviderComponentGetAll]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ServiceProviderComponentGetAll]
GO
CREATE PROCEDURE [dbo].[ServiceProviderComponentGetAll]
AS
	SELECT	ServiceProviderID,
		ServiceComponentID
	FROM	[dbo].[ServiceProviderComponent]
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ServiceProviderComponentAdd]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ServiceProviderComponentAdd]
GO
CREATE PROCEDURE [dbo].[ServiceProviderComponentAdd]
	@ServiceProviderID	int,
	@ServiceComponentID	int
AS
	INSERT INTO  dbo.ServiceProviderComponent (
		ServiceProviderID,
		ServiceComponentID
	)
	VALUES (
		@ServiceProviderID,
		@ServiceComponentID
	)
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ServiceProviderComponentSchema]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ServiceProviderComponentSchema]
GO
CREATE PROCEDURE [dbo].[ServiceProviderComponentSchema]
AS
	SELECT
	'IF OBJECT_ID(''tempdb..#ServiceProviderComponent'') IS NULL' + CAST(0x0A AS CHAR(1)) +
	'	CREATE TABLE #ServiceProviderComponent (' + CAST(0x0A AS CHAR(1)) +
	'		ServiceProviderID	int NOT NULL,' + CAST(0x0A AS CHAR(1)) +
	'		ServiceComponentID	int NOT NULL' + CAST(0x0A AS CHAR(1)) +
	'	)' + CAST(0x0A AS CHAR(1)) +
	'ELSE' + CAST(0x0A AS CHAR(1)) +
	'	DELETE FROM #ServiceProviderComponent' + CAST(0x0A AS CHAR(1)) +
	'' AS SQL
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ServiceProviderComponentTempAdd]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ServiceProviderComponentTempAdd]
GO
CREATE PROCEDURE dbo.[ServiceProviderComponentTempAdd]
	@ServiceProviderID	int,
	@ServiceComponentID	int
AS
	INSERT INTO #ServiceProviderComponent (
		ServiceProviderID,
		ServiceComponentID
	)
	VALUES (
		@ServiceProviderID,
		@ServiceComponentID
	)
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ServiceProviderComponentAddBatch]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ServiceProviderComponentAddBatch]
GO
CREATE PROCEDURE dbo.[ServiceProviderComponentAddBatch]
AS
	DECLARE @count int
	INSERT dbo.ServiceProviderComponent (
		ServiceProviderID,
		ServiceComponentID
	)
		SELECT	ServiceProviderID,
			ServiceComponentID
		FROM #ServiceProviderComponent
	SET @count = @@ROWCOUNT
	DROP TABLE #ServiceProviderComponent	-- Drop temporary table
	RETURN @count
GO

/*
Add new ServiceProviderComponent bound to
	ServiceComponent using Name, Version, Publisher, Edition
	with ServiceProviderID
*/

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ServiceProviderComponentPutByServiceProviderIDServiceComponentID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ServiceProviderComponentPutByServiceProviderIDServiceComponentID]
GO
CREATE PROCEDURE [dbo].[ServiceProviderComponentPutByServiceProviderIDServiceComponentID]
	@ServiceProviderID	int,
	@ServiceComponentID	int
AS
	IF NOT EXISTS(
		SELECT	1
		FROM	dbo.ServiceProviderComponent
		WHERE	ServiceProviderID = @ServiceProviderID
		  AND	ServiceComponentID = @ServiceComponentID
	)
		EXEC ServiceProviderComponentAdd @ServiceProviderID,
			@ServiceComponentID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ServiceProviderComponentPutBatchByServiceProviderIDServiceComponentID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ServiceProviderComponentPutBatchByServiceProviderIDServiceComponentID]
GO
CREATE PROCEDURE [dbo].[ServiceProviderComponentPutBatchByServiceProviderIDServiceComponentID]
AS
	DECLARE @count AS int
	SET @count = 0

	CREATE INDEX [TempServiceProviderComponentServiceProviderIDServiceComponentID]
		ON #ServiceProviderComponent (ServiceProviderID, ServiceComponentID)

	BEGIN TRANSACTION

	INSERT [dbo].[ServiceProviderComponent] (
		ServiceProviderID,
		ServiceComponentID
	)
		SELECT	ServiceProviderID,
			ServiceComponentID
		FROM	#ServiceProviderComponent AS t
		WHERE NOT EXISTS(	-- Current record doesn't exist
			SELECT * FROM [dbo].[ServiceProviderComponent]
			WHERE	ServiceProviderComponent.ServiceProviderID = t.ServiceProviderID
			  AND	ServiceProviderComponent.ServiceComponentID = t.ServiceComponentID
		)
	SET @count = @count + @@ROWCOUNT
	DROP TABLE #ServiceProviderComponent	-- Drop the temporary table
	COMMIT WORK
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ServiceProviderComponentRemoveBatch]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ServiceProviderComponentRemoveBatch]
GO

CREATE PROCEDURE [dbo].[ServiceProviderComponentRemoveBatch]
AS

	CREATE INDEX [TempServiceProviderComponentServiceProviderComponentRemoveBatch]
		ON #ServiceProviderComponent (ServiceProviderID, ServiceComponentID)	

	-- Delete records from ServiceProviderComponent identified by fields of [TempServiceProviderComponentServiceProviderComponentRemoveBatch]
	DELETE [dbo].[ServiceProviderComponent]
	WHERE EXISTS(
			SELECT * FROM #ServiceProviderComponent AS t
			WHERE	ServiceProviderComponent.ServiceProviderID = t.ServiceProviderID
			  AND	ServiceProviderComponent.ServiceComponentID = t.ServiceComponentID
		)
	DROP TABLE #ServiceProviderComponent      -- Drop the temporary table
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ServiceProviderComponentRemoveByServiceProviderIDServiceComponentID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ServiceProviderComponentRemoveByServiceProviderIDServiceComponentID]
GO
CREATE PROCEDURE [dbo].[ServiceProviderComponentRemoveByServiceProviderIDServiceComponentID]
	@ServiceProviderID	int,
	@ServiceComponentID	int
AS
	DELETE	[dbo].[ServiceProviderComponent]
	WHERE	ServiceProviderID = @ServiceProviderID
	  AND	ServiceComponentID = @ServiceComponentID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ServiceProviderComponentRemoveAllByServiceProviderID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ServiceProviderComponentRemoveAllByServiceProviderID]
GO
CREATE PROCEDURE [dbo].[ServiceProviderComponentRemoveAllByServiceProviderID]
	@ServiceProviderID	int
AS
	DELETE	[dbo].[ServiceProviderComponent]
	WHERE	ServiceProviderID = @ServiceProviderID
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ServiceProviderComponentRemoveAll]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ServiceProviderComponentRemoveAll]
GO
CREATE PROCEDURE [dbo].[ServiceProviderComponentRemoveAll]
	
AS
	DELETE	[dbo].[ServiceProviderComponent]
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ServiceProviderComponentReplaceSubsetByServiceProviderID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ServiceProviderComponentReplaceSubsetByServiceProviderID]
GO
-- Replace the record subset selected by (@ServiceProviderID)
-- using unique identifier (ServiceProviderID, ServiceComponentID)
CREATE PROCEDURE [dbo].[ServiceProviderComponentReplaceSubsetByServiceProviderID]
	@ServiceProviderID	int
AS
	DECLARE @count AS int
	SET @count = 0

	CREATE INDEX [TempServiceProviderComponentByServiceProviderID]
		ON #ServiceProviderComponent (ServiceProviderID, ServiceComponentID)

	BEGIN TRANSACTION
	DELETE [ServiceProviderComponent]
		WHERE	ServiceProviderID = @ServiceProviderID
		AND NOT EXISTS(		-- Replacement record doesn't exist
			SELECT * FROM #ServiceProviderComponent AS t
			WHERE	ServiceProviderComponent.ServiceProviderID = t.ServiceProviderID
			  AND	ServiceProviderComponent.ServiceComponentID = t.ServiceComponentID
		)

	INSERT [ServiceProviderComponent] (
		ServiceProviderID,
		ServiceComponentID
	)
		SELECT	ServiceProviderID,
			ServiceComponentID
		FROM	#ServiceProviderComponent AS t
		WHERE NOT EXISTS(	-- Current record doesn't exist
			SELECT * FROM [ServiceProviderComponent]
			WHERE	ServiceProviderComponent.ServiceProviderID = t.ServiceProviderID
			  AND	ServiceProviderComponent.ServiceComponentID = t.ServiceComponentID
		)
	SET @count = @count + @@ROWCOUNT
	DROP TABLE #ServiceProviderComponent	-- Drop the temporary table
	COMMIT WORK
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ServiceProviderComponentPropertyGetByProperty]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ServiceProviderComponentPropertyGetByProperty]
GO
CREATE PROCEDURE [dbo].[ServiceProviderComponentPropertyGetByProperty]
	@Property		nvarchar(256)
AS
	SELECT	ServiceProviderComponentPropertyID,
		Property
	FROM	[dbo].[ServiceProviderComponentProperty]
	WHERE	Property = @Property
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ServiceProviderComponentPropertyGetByID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ServiceProviderComponentPropertyGetByID]
GO
CREATE PROCEDURE [dbo].[ServiceProviderComponentPropertyGetByID]
	@ServiceProviderComponentPropertyID int
AS
	SELECT	ServiceProviderComponentPropertyID,
		Property
	FROM	[dbo].[ServiceProviderComponentProperty]
	WHERE	ServiceProviderComponentPropertyID = @ServiceProviderComponentPropertyID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ServiceProviderComponentPropertyGetAll]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ServiceProviderComponentPropertyGetAll]
GO
CREATE PROCEDURE [dbo].[ServiceProviderComponentPropertyGetAll]
AS
	SELECT	ServiceProviderComponentPropertyID,
		Property
	FROM	[dbo].[ServiceProviderComponentProperty]
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ServiceProviderComponentPropertyAdd]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ServiceProviderComponentPropertyAdd]
GO
CREATE PROCEDURE [dbo].[ServiceProviderComponentPropertyAdd]
	@Property		nvarchar(256)
AS
	INSERT INTO  dbo.ServiceProviderComponentProperty (
		Property
	)
	VALUES (
		@Property
	)
	RETURN SCOPE_IDENTITY()
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ServiceProviderComponentPropertyBind]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ServiceProviderComponentPropertyBind]
GO
CREATE PROCEDURE [dbo].[ServiceProviderComponentPropertyBind]
	@Property		nvarchar(256)
AS
	DECLARE	@ID	int

	SELECT	@ID = ServiceProviderComponentPropertyID
	FROM	[dbo].[ServiceProviderComponentProperty]
	WHERE	Property = @Property

	IF @ID IS NULL
		EXEC @ID = ServiceProviderComponentPropertyAdd @Property

	RETURN @ID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ServiceProviderComponentPropertySchema]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ServiceProviderComponentPropertySchema]
GO
CREATE PROCEDURE [dbo].[ServiceProviderComponentPropertySchema]
AS
	SELECT
	'IF OBJECT_ID(''tempdb..#ServiceProviderComponentProperty'') IS NULL' + CAST(0x0A AS CHAR(1)) +
	'	CREATE TABLE #ServiceProviderComponentProperty (' + CAST(0x0A AS CHAR(1)) +
	'		ServiceProviderComponentPropertyID int NULL,' + CAST(0x0A AS CHAR(1)) +
	'		Property		nvarchar(256) COLLATE database_default NOT NULL' + CAST(0x0A AS CHAR(1)) +
	'	)' + CAST(0x0A AS CHAR(1)) +
	'ELSE' + CAST(0x0A AS CHAR(1)) +
	'	DELETE FROM #ServiceProviderComponentProperty' + CAST(0x0A AS CHAR(1)) +
	'' AS SQL
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ServiceProviderComponentPropertyTempAdd]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ServiceProviderComponentPropertyTempAdd]
GO
CREATE PROCEDURE dbo.[ServiceProviderComponentPropertyTempAdd]
	@ServiceProviderComponentPropertyID int,
	@Property		nvarchar(256)
AS
	INSERT INTO #ServiceProviderComponentProperty (
		ServiceProviderComponentPropertyID,
		Property
	)
	VALUES (
		@ServiceProviderComponentPropertyID,
		@Property
	)
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ServiceProviderComponentPropertyAddBatch]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ServiceProviderComponentPropertyAddBatch]
GO
CREATE PROCEDURE dbo.[ServiceProviderComponentPropertyAddBatch]
AS
	DECLARE @count int
	INSERT dbo.ServiceProviderComponentProperty (
		Property
	)
		SELECT	Property
		FROM #ServiceProviderComponentProperty
	SET @count = @@ROWCOUNT
	DROP TABLE #ServiceProviderComponentProperty	-- Drop temporary table
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ServiceProviderComponentPropertyUpdateByID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ServiceProviderComponentPropertyUpdateByID]
GO
CREATE PROCEDURE [dbo].[ServiceProviderComponentPropertyUpdateByID]
	@ServiceProviderComponentPropertyID int,
	@Property		nvarchar(256)
AS
	DECLARE	@ID	int
	SET @ID = 0

	UPDATE	[dbo].[ServiceProviderComponentProperty]
	SET	@ID = ServiceProviderComponentPropertyID,
		Property = @Property
	WHERE	ServiceProviderComponentPropertyID = @ServiceProviderComponentPropertyID
	RETURN @ID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ServiceProviderComponentPropertyUpdateBatchByID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ServiceProviderComponentPropertyUpdateBatchByID]
GO
CREATE PROCEDURE dbo.[ServiceProviderComponentPropertyUpdateBatchByID]
AS
	DECLARE @count int

	CREATE INDEX [TempServiceProviderComponentPropertyID]
		ON #ServiceProviderComponentProperty (ServiceProviderComponentPropertyID)

	UPDATE	[dbo].[ServiceProviderComponentProperty]
	SET	Property = t.Property
	FROM	#ServiceProviderComponentProperty AS t
	WHERE	ServiceProviderComponentProperty.ServiceProviderComponentPropertyID = t.ServiceProviderComponentPropertyID
	SET @count = @@ROWCOUNT
	DROP TABLE #ServiceProviderComponentProperty	-- Drop the temporary table
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ServiceProviderComponentPropertyPutByProperty]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ServiceProviderComponentPropertyPutByProperty]
GO
CREATE PROCEDURE [dbo].[ServiceProviderComponentPropertyPutByProperty]
	@Property		nvarchar(256)
AS
	DECLARE @ID	int

	SELECT	@ID = ServiceProviderComponentPropertyID
	FROM	ServiceProviderComponentProperty
	WHERE	Property = @Property

	IF @ID IS NULL
		EXEC @ID = ServiceProviderComponentPropertyAdd @Property

	RETURN @ID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ServiceProviderComponentPropertyPutBatchByProperty]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ServiceProviderComponentPropertyPutBatchByProperty]
GO
CREATE PROCEDURE [dbo].[ServiceProviderComponentPropertyPutBatchByProperty]
AS
	DECLARE @count AS int
	SET @count = 0

	CREATE INDEX [TempServiceProviderComponentPropertyProperty]
		ON #ServiceProviderComponentProperty (Property)

	BEGIN TRANSACTION

	INSERT [dbo].[ServiceProviderComponentProperty] (
		Property
	)
		SELECT	Property
		FROM	#ServiceProviderComponentProperty AS t
		WHERE NOT EXISTS(	-- Current record doesn't exist
			SELECT * FROM [dbo].[ServiceProviderComponentProperty]
			WHERE	ServiceProviderComponentProperty.Property = t.Property
		)
	SET @count = @count + @@ROWCOUNT
	DROP TABLE #ServiceProviderComponentProperty	-- Drop the temporary table
	COMMIT WORK
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ServiceProviderComponentPropertyRemoveBatch]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ServiceProviderComponentPropertyRemoveBatch]
GO

CREATE PROCEDURE [dbo].[ServiceProviderComponentPropertyRemoveBatch]
AS

	CREATE INDEX [TempServiceProviderComponentPropertyServiceProviderComponentPropertyRemoveBatch]
		ON #ServiceProviderComponentProperty (ServiceProviderComponentPropertyID)	

	-- Delete records from ServiceProviderComponentProperty identified by fields of [TempServiceProviderComponentPropertyServiceProviderComponentPropertyRemoveBatch]
	DELETE [dbo].[ServiceProviderComponentProperty]
	WHERE EXISTS(
			SELECT * FROM #ServiceProviderComponentProperty AS t
			WHERE	ServiceProviderComponentProperty.ServiceProviderComponentPropertyID = t.ServiceProviderComponentPropertyID
		)
	DROP TABLE #ServiceProviderComponentProperty      -- Drop the temporary table
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ServiceProviderComponentPropertyRemoveByProperty]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ServiceProviderComponentPropertyRemoveByProperty]
GO
CREATE PROCEDURE [dbo].[ServiceProviderComponentPropertyRemoveByProperty]
	@Property		nvarchar(256)
AS
	-- ServiceProviderComponentProperty deletes cascade to:
	--	ServiceProviderComponentValue by FK_ServiceProviderComponentValue_ServiceProviderComponentProperty
	DELETE	[dbo].[ServiceProviderComponentProperty]
	WHERE	Property = @Property
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ServiceProviderComponentPropertyRemoveAll]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ServiceProviderComponentPropertyRemoveAll]
GO
CREATE PROCEDURE [dbo].[ServiceProviderComponentPropertyRemoveAll]
	
AS
	DELETE	[dbo].[ServiceProviderComponentProperty]
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ServiceProviderComponentValueGetByServiceProviderIDServiceComponentIDServiceProviderComponentPropertyID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ServiceProviderComponentValueGetByServiceProviderIDServiceComponentIDServiceProviderComponentPropertyID]
GO
CREATE PROCEDURE [dbo].[ServiceProviderComponentValueGetByServiceProviderIDServiceComponentIDServiceProviderComponentPropertyID]
	@ServiceProviderID	int,
	@ServiceComponentID	int,
	@ServiceProviderComponentPropertyID int
AS
	SELECT	ServiceProviderID,
		ServiceComponentID,
		ServiceProviderComponentPropertyID,
		Value
	FROM	[dbo].[ServiceProviderComponentValue]
	WHERE	ServiceProviderID = @ServiceProviderID
	  AND	ServiceComponentID = @ServiceComponentID
	  AND	ServiceProviderComponentPropertyID = @ServiceProviderComponentPropertyID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ServiceProviderComponentValueGetAllByServiceProviderIDServiceComponentID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ServiceProviderComponentValueGetAllByServiceProviderIDServiceComponentID]
GO
CREATE PROCEDURE [dbo].[ServiceProviderComponentValueGetAllByServiceProviderIDServiceComponentID]
	@ServiceProviderID	int,
	@ServiceComponentID	int
AS
	SELECT	ServiceProviderID,
		ServiceComponentID,
		ServiceProviderComponentPropertyID,
		Value
	FROM	[dbo].[ServiceProviderComponentValue]
	WHERE	ServiceProviderID = @ServiceProviderID
	  AND	ServiceComponentID = @ServiceComponentID
	ORDER BY ServiceProviderComponentPropertyID
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ServiceProviderComponentValueGetAllByServiceProviderID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ServiceProviderComponentValueGetAllByServiceProviderID]
GO
CREATE PROCEDURE [dbo].[ServiceProviderComponentValueGetAllByServiceProviderID]
	@ServiceProviderID	int
AS
	SELECT	ServiceProviderID,
		ServiceComponentID,
		ServiceProviderComponentPropertyID,
		Value
	FROM	[dbo].[ServiceProviderComponentValue]
	WHERE	ServiceProviderID = @ServiceProviderID
	ORDER BY ServiceComponentID, ServiceProviderComponentPropertyID
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ServiceProviderComponentValueGetAll]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ServiceProviderComponentValueGetAll]
GO
CREATE PROCEDURE [dbo].[ServiceProviderComponentValueGetAll]
AS
	SELECT	ServiceProviderID,
		ServiceComponentID,
		ServiceProviderComponentPropertyID,
		Value
	FROM	[dbo].[ServiceProviderComponentValue]
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ServiceProviderComponentValueAdd]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ServiceProviderComponentValueAdd]
GO
CREATE PROCEDURE [dbo].[ServiceProviderComponentValueAdd]
	@ServiceProviderID	int,
	@ServiceComponentID	int,
	@ServiceProviderComponentPropertyID int,
	@Value			nvarchar(256) = NULL
AS
	INSERT INTO  dbo.ServiceProviderComponentValue (
		ServiceProviderID,
		ServiceComponentID,
		ServiceProviderComponentPropertyID,
		Value
	)
	VALUES (
		@ServiceProviderID,
		@ServiceComponentID,
		@ServiceProviderComponentPropertyID,
		@Value
	)
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ServiceProviderComponentValueSchema]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ServiceProviderComponentValueSchema]
GO
CREATE PROCEDURE [dbo].[ServiceProviderComponentValueSchema]
AS
	SELECT
	'IF OBJECT_ID(''tempdb..#ServiceProviderComponentValue'') IS NULL' + CAST(0x0A AS CHAR(1)) +
	'	CREATE TABLE #ServiceProviderComponentValue (' + CAST(0x0A AS CHAR(1)) +
	'		ServiceProviderID	int NOT NULL,' + CAST(0x0A AS CHAR(1)) +
	'		ServiceComponentID	int NOT NULL,' + CAST(0x0A AS CHAR(1)) +
	'		ServiceProviderComponentPropertyID int NOT NULL,' + CAST(0x0A AS CHAR(1)) +
	'		Value			nvarchar(256) COLLATE database_default NULL' + CAST(0x0A AS CHAR(1)) +
	'	)' + CAST(0x0A AS CHAR(1)) +
	'ELSE' + CAST(0x0A AS CHAR(1)) +
	'	DELETE FROM #ServiceProviderComponentValue' + CAST(0x0A AS CHAR(1)) +
	'' AS SQL
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ServiceProviderComponentValueTempAdd]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ServiceProviderComponentValueTempAdd]
GO
CREATE PROCEDURE dbo.[ServiceProviderComponentValueTempAdd]
	@ServiceProviderID	int,
	@ServiceComponentID	int,
	@ServiceProviderComponentPropertyID int,
	@Value			nvarchar(256) = NULL
AS
	INSERT INTO #ServiceProviderComponentValue (
		ServiceProviderID,
		ServiceComponentID,
		ServiceProviderComponentPropertyID,
		Value
	)
	VALUES (
		@ServiceProviderID,
		@ServiceComponentID,
		@ServiceProviderComponentPropertyID,
		@Value
	)
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ServiceProviderComponentValueAddBatch]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ServiceProviderComponentValueAddBatch]
GO
CREATE PROCEDURE dbo.[ServiceProviderComponentValueAddBatch]
AS
	DECLARE @count int
	INSERT dbo.ServiceProviderComponentValue (
		ServiceProviderID,
		ServiceComponentID,
		ServiceProviderComponentPropertyID,
		Value
	)
		SELECT	ServiceProviderID,
			ServiceComponentID,
			ServiceProviderComponentPropertyID,
			Value
		FROM #ServiceProviderComponentValue
	SET @count = @@ROWCOUNT
	DROP TABLE #ServiceProviderComponentValue	-- Drop temporary table
	RETURN @count
GO

/*
Add new ServiceProviderComponentValue bound to
	ServiceComponent using Name, Version, Publisher, Edition
	ServiceProviderComponentProperty using Property
	with ServiceProviderID, Value
*/

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ServiceProviderComponentValueUpdateByServiceProviderIDServiceComponentIDServiceProviderComponentPropertyID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ServiceProviderComponentValueUpdateByServiceProviderIDServiceComponentIDServiceProviderComponentPropertyID]
GO
CREATE PROCEDURE [dbo].[ServiceProviderComponentValueUpdateByServiceProviderIDServiceComponentIDServiceProviderComponentPropertyID]
	@ServiceProviderID	int,
	@ServiceComponentID	int,
	@ServiceProviderComponentPropertyID int,
	@Value			nvarchar(256) = NULL
AS
	UPDATE	[dbo].[ServiceProviderComponentValue]
	SET	Value = @Value
	WHERE	ServiceProviderID = @ServiceProviderID
	  AND	ServiceComponentID = @ServiceComponentID
	  AND	ServiceProviderComponentPropertyID = @ServiceProviderComponentPropertyID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ServiceProviderComponentValueUpdateBatchByServiceProviderIDServiceComponentIDServiceProviderComponentPropertyID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ServiceProviderComponentValueUpdateBatchByServiceProviderIDServiceComponentIDServiceProviderComponentPropertyID]
GO
CREATE PROCEDURE dbo.[ServiceProviderComponentValueUpdateBatchByServiceProviderIDServiceComponentIDServiceProviderComponentPropertyID]
AS
	DECLARE @count int

	CREATE INDEX [TempServiceProviderComponentValueServiceProviderIDServiceComponentIDServiceProviderComponentPropertyID]
		ON #ServiceProviderComponentValue (ServiceProviderID, ServiceComponentID, ServiceProviderComponentPropertyID)

	UPDATE	[dbo].[ServiceProviderComponentValue]
	SET	Value = t.Value
	FROM	#ServiceProviderComponentValue AS t
	WHERE	ServiceProviderComponentValue.ServiceProviderID = t.ServiceProviderID
	  AND	ServiceProviderComponentValue.ServiceComponentID = t.ServiceComponentID
	  AND	ServiceProviderComponentValue.ServiceProviderComponentPropertyID = t.ServiceProviderComponentPropertyID
	SET @count = @@ROWCOUNT
	DROP TABLE #ServiceProviderComponentValue	-- Drop the temporary table
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ServiceProviderComponentValuePutByServiceProviderIDServiceComponentIDServiceProviderComponentPropertyID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ServiceProviderComponentValuePutByServiceProviderIDServiceComponentIDServiceProviderComponentPropertyID]
GO
CREATE PROCEDURE [dbo].[ServiceProviderComponentValuePutByServiceProviderIDServiceComponentIDServiceProviderComponentPropertyID]
	@ServiceProviderID	int,
	@ServiceComponentID	int,
	@ServiceProviderComponentPropertyID int,
	@Value			nvarchar(256) = NULL
AS
	IF NOT EXISTS(
		SELECT	1
		FROM	dbo.ServiceProviderComponentValue
		WHERE	ServiceProviderID = @ServiceProviderID
		  AND	ServiceComponentID = @ServiceComponentID
		  AND	ServiceProviderComponentPropertyID = @ServiceProviderComponentPropertyID
	)
		EXEC ServiceProviderComponentValueAdd @ServiceProviderID,
			@ServiceComponentID,
			@ServiceProviderComponentPropertyID,
			@Value
	ELSE
		EXEC ServiceProviderComponentValueUpdateByServiceProviderIDServiceComponentIDServiceProviderComponentPropertyID @ServiceProviderID,
			@ServiceComponentID,
			@ServiceProviderComponentPropertyID,
			@Value
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ServiceProviderComponentValuePutBatchByServiceProviderIDServiceComponentIDServiceProviderComponentPropertyID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ServiceProviderComponentValuePutBatchByServiceProviderIDServiceComponentIDServiceProviderComponentPropertyID]
GO
CREATE PROCEDURE [dbo].[ServiceProviderComponentValuePutBatchByServiceProviderIDServiceComponentIDServiceProviderComponentPropertyID]
AS
	DECLARE @count AS int
	SET @count = 0

	CREATE INDEX [TempServiceProviderComponentValueServiceProviderIDServiceComponentIDServiceProviderComponentPropertyID]
		ON #ServiceProviderComponentValue (ServiceProviderID, ServiceComponentID, ServiceProviderComponentPropertyID)

	BEGIN TRANSACTION
	UPDATE [dbo].[ServiceProviderComponentValue]
		SET	Value = t.Value
		FROM	#ServiceProviderComponentValue AS t
		WHERE	ServiceProviderComponentValue.ServiceProviderID = t.ServiceProviderID
		  AND	ServiceProviderComponentValue.ServiceComponentID = t.ServiceComponentID
		  AND	ServiceProviderComponentValue.ServiceProviderComponentPropertyID = t.ServiceProviderComponentPropertyID
	SET @count = @@ROWCOUNT

	INSERT [dbo].[ServiceProviderComponentValue] (
		ServiceProviderID,
		ServiceComponentID,
		ServiceProviderComponentPropertyID,
		Value
	)
		SELECT	ServiceProviderID,
			ServiceComponentID,
			ServiceProviderComponentPropertyID,
			Value
		FROM	#ServiceProviderComponentValue AS t
		WHERE NOT EXISTS(	-- Current record doesn't exist
			SELECT * FROM [dbo].[ServiceProviderComponentValue]
			WHERE	ServiceProviderComponentValue.ServiceProviderID = t.ServiceProviderID
			  AND	ServiceProviderComponentValue.ServiceComponentID = t.ServiceComponentID
			  AND	ServiceProviderComponentValue.ServiceProviderComponentPropertyID = t.ServiceProviderComponentPropertyID
		)
	SET @count = @count + @@ROWCOUNT
	DROP TABLE #ServiceProviderComponentValue	-- Drop the temporary table
	COMMIT WORK
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ServiceProviderComponentValueRemoveBatch]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ServiceProviderComponentValueRemoveBatch]
GO

CREATE PROCEDURE [dbo].[ServiceProviderComponentValueRemoveBatch]
AS

	CREATE INDEX [TempServiceProviderComponentValueServiceProviderComponentValueRemoveBatch]
		ON #ServiceProviderComponentValue (ServiceProviderID, ServiceComponentID, ServiceProviderComponentPropertyID)	

	-- Delete records from ServiceProviderComponentValue identified by fields of [TempServiceProviderComponentValueServiceProviderComponentValueRemoveBatch]
	DELETE [dbo].[ServiceProviderComponentValue]
	WHERE EXISTS(
			SELECT * FROM #ServiceProviderComponentValue AS t
			WHERE	ServiceProviderComponentValue.ServiceProviderID = t.ServiceProviderID
			  AND	ServiceProviderComponentValue.ServiceComponentID = t.ServiceComponentID
			  AND	ServiceProviderComponentValue.ServiceProviderComponentPropertyID = t.ServiceProviderComponentPropertyID
		)
	DROP TABLE #ServiceProviderComponentValue      -- Drop the temporary table
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ServiceProviderComponentValueRemoveByServiceProviderIDServiceComponentIDServiceProviderComponentPropertyID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ServiceProviderComponentValueRemoveByServiceProviderIDServiceComponentIDServiceProviderComponentPropertyID]
GO
CREATE PROCEDURE [dbo].[ServiceProviderComponentValueRemoveByServiceProviderIDServiceComponentIDServiceProviderComponentPropertyID]
	@ServiceProviderID	int,
	@ServiceComponentID	int,
	@ServiceProviderComponentPropertyID int
AS
	DELETE	[dbo].[ServiceProviderComponentValue]
	WHERE	ServiceProviderID = @ServiceProviderID
	  AND	ServiceComponentID = @ServiceComponentID
	  AND	ServiceProviderComponentPropertyID = @ServiceProviderComponentPropertyID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ServiceProviderComponentValueRemoveAllByServiceProviderIDServiceComponentID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ServiceProviderComponentValueRemoveAllByServiceProviderIDServiceComponentID]
GO
CREATE PROCEDURE [dbo].[ServiceProviderComponentValueRemoveAllByServiceProviderIDServiceComponentID]
	@ServiceProviderID	int,
	@ServiceComponentID	int
AS
	DELETE	[dbo].[ServiceProviderComponentValue]
	WHERE	ServiceProviderID = @ServiceProviderID
	  AND	ServiceComponentID = @ServiceComponentID
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ServiceProviderComponentValueRemoveAllByServiceProviderID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ServiceProviderComponentValueRemoveAllByServiceProviderID]
GO
CREATE PROCEDURE [dbo].[ServiceProviderComponentValueRemoveAllByServiceProviderID]
	@ServiceProviderID	int
AS
	DELETE	[dbo].[ServiceProviderComponentValue]
	WHERE	ServiceProviderID = @ServiceProviderID
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ServiceProviderComponentValueRemoveAll]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ServiceProviderComponentValueRemoveAll]
GO
CREATE PROCEDURE [dbo].[ServiceProviderComponentValueRemoveAll]
	
AS
	DELETE	[dbo].[ServiceProviderComponentValue]
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ServiceProviderComponentValueReplaceSubsetByServiceProviderIDServiceComponentID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ServiceProviderComponentValueReplaceSubsetByServiceProviderIDServiceComponentID]
GO
-- Replace the record subset selected by (@ServiceProviderID, @ServiceComponentID)
-- using unique identifier (ServiceProviderID, ServiceComponentID, ServiceProviderComponentPropertyID)
-- updating fields (Value)
CREATE PROCEDURE [dbo].[ServiceProviderComponentValueReplaceSubsetByServiceProviderIDServiceComponentID]
	@ServiceProviderID	int,
	@ServiceComponentID	int
AS
	DECLARE @count AS int
	SET @count = 0

	CREATE INDEX [TempServiceProviderComponentValueByServiceProviderIDServiceComponentID]
		ON #ServiceProviderComponentValue (ServiceProviderID, ServiceComponentID, ServiceProviderComponentPropertyID)

	BEGIN TRANSACTION
	DELETE [ServiceProviderComponentValue]
		WHERE	ServiceProviderID = @ServiceProviderID
		  AND	ServiceComponentID = @ServiceComponentID
		AND NOT EXISTS(		-- Replacement record doesn't exist
			SELECT * FROM #ServiceProviderComponentValue AS t
			WHERE	ServiceProviderComponentValue.ServiceProviderID = t.ServiceProviderID
			  AND	ServiceProviderComponentValue.ServiceComponentID = t.ServiceComponentID
			  AND	ServiceProviderComponentValue.ServiceProviderComponentPropertyID = t.ServiceProviderComponentPropertyID
		)

	UPDATE [dbo].[ServiceProviderComponentValue]
		SET	Value = t.Value
		FROM	#ServiceProviderComponentValue AS t
		WHERE	ServiceProviderComponentValue.ServiceProviderID = t.ServiceProviderID
		  AND	ServiceProviderComponentValue.ServiceComponentID = t.ServiceComponentID
		  AND	ServiceProviderComponentValue.ServiceProviderComponentPropertyID = t.ServiceProviderComponentPropertyID
	SET @count = @@ROWCOUNT

	INSERT [ServiceProviderComponentValue] (
		ServiceProviderID,
		ServiceComponentID,
		ServiceProviderComponentPropertyID,
		Value
	)
		SELECT	ServiceProviderID,
			ServiceComponentID,
			ServiceProviderComponentPropertyID,
			Value
		FROM	#ServiceProviderComponentValue AS t
		WHERE NOT EXISTS(	-- Current record doesn't exist
			SELECT * FROM [ServiceProviderComponentValue]
			WHERE	ServiceProviderComponentValue.ServiceProviderID = t.ServiceProviderID
			  AND	ServiceProviderComponentValue.ServiceComponentID = t.ServiceComponentID
			  AND	ServiceProviderComponentValue.ServiceProviderComponentPropertyID = t.ServiceProviderComponentPropertyID
		)
	SET @count = @count + @@ROWCOUNT
	DROP TABLE #ServiceProviderComponentValue	-- Drop the temporary table
	COMMIT WORK
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ServiceProviderComponentValueReplaceSubsetByServiceProviderID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ServiceProviderComponentValueReplaceSubsetByServiceProviderID]
GO
-- Replace the record subset selected by (@ServiceProviderID)
-- using unique identifier (ServiceProviderID, ServiceComponentID, ServiceProviderComponentPropertyID)
-- updating fields (Value)
CREATE PROCEDURE [dbo].[ServiceProviderComponentValueReplaceSubsetByServiceProviderID]
	@ServiceProviderID	int
AS
	DECLARE @count AS int
	SET @count = 0

	CREATE INDEX [TempServiceProviderComponentValueByServiceProviderID]
		ON #ServiceProviderComponentValue (ServiceProviderID, ServiceComponentID, ServiceProviderComponentPropertyID)

	BEGIN TRANSACTION
	DELETE [ServiceProviderComponentValue]
		WHERE	ServiceProviderID = @ServiceProviderID
		AND NOT EXISTS(		-- Replacement record doesn't exist
			SELECT * FROM #ServiceProviderComponentValue AS t
			WHERE	ServiceProviderComponentValue.ServiceProviderID = t.ServiceProviderID
			  AND	ServiceProviderComponentValue.ServiceComponentID = t.ServiceComponentID
			  AND	ServiceProviderComponentValue.ServiceProviderComponentPropertyID = t.ServiceProviderComponentPropertyID
		)

	UPDATE [dbo].[ServiceProviderComponentValue]
		SET	Value = t.Value
		FROM	#ServiceProviderComponentValue AS t
		WHERE	ServiceProviderComponentValue.ServiceProviderID = t.ServiceProviderID
		  AND	ServiceProviderComponentValue.ServiceComponentID = t.ServiceComponentID
		  AND	ServiceProviderComponentValue.ServiceProviderComponentPropertyID = t.ServiceProviderComponentPropertyID
	SET @count = @@ROWCOUNT

	INSERT [ServiceProviderComponentValue] (
		ServiceProviderID,
		ServiceComponentID,
		ServiceProviderComponentPropertyID,
		Value
	)
		SELECT	ServiceProviderID,
			ServiceComponentID,
			ServiceProviderComponentPropertyID,
			Value
		FROM	#ServiceProviderComponentValue AS t
		WHERE NOT EXISTS(	-- Current record doesn't exist
			SELECT * FROM [ServiceProviderComponentValue]
			WHERE	ServiceProviderComponentValue.ServiceProviderID = t.ServiceProviderID
			  AND	ServiceProviderComponentValue.ServiceComponentID = t.ServiceComponentID
			  AND	ServiceProviderComponentValue.ServiceProviderComponentPropertyID = t.ServiceProviderComponentPropertyID
		)
	SET @count = @count + @@ROWCOUNT
	DROP TABLE #ServiceProviderComponentValue	-- Drop the temporary table
	COMMIT WORK
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ServiceUserGetByServiceProviderIDName]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ServiceUserGetByServiceProviderIDName]
GO
CREATE PROCEDURE [dbo].[ServiceUserGetByServiceProviderIDName]
	@ServiceProviderID	int,
	@Name			nvarchar(128)
AS
	SELECT	ServiceUserID,
		ServiceProviderID,
		[Name],
		Description,
		AccountStatus,
		CreationDate,
		LastLogonDate
	FROM	[dbo].[ServiceUser]
	WHERE	ServiceProviderID = @ServiceProviderID
	  AND	[Name] = @Name
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ServiceUserGetAllByServiceProviderID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ServiceUserGetAllByServiceProviderID]
GO
CREATE PROCEDURE [dbo].[ServiceUserGetAllByServiceProviderID]
	@ServiceProviderID	int
AS
	SELECT	ServiceUserID,
		ServiceProviderID,
		[Name],
		Description,
		AccountStatus,
		CreationDate,
		LastLogonDate
	FROM	[dbo].[ServiceUser]
	WHERE	ServiceProviderID = @ServiceProviderID
	ORDER BY [Name]
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ServiceUserGetByID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ServiceUserGetByID]
GO
CREATE PROCEDURE [dbo].[ServiceUserGetByID]
	@ServiceUserID		int
AS
	SELECT	ServiceUserID,
		ServiceProviderID,
		[Name],
		Description,
		AccountStatus,
		CreationDate,
		LastLogonDate
	FROM	[dbo].[ServiceUser]
	WHERE	ServiceUserID = @ServiceUserID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ServiceUserGetAll]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ServiceUserGetAll]
GO
CREATE PROCEDURE [dbo].[ServiceUserGetAll]
AS
	SELECT	ServiceUserID,
		ServiceProviderID,
		[Name],
		Description,
		AccountStatus,
		CreationDate,
		LastLogonDate
	FROM	[dbo].[ServiceUser]
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ServiceUserAdd]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ServiceUserAdd]
GO
CREATE PROCEDURE [dbo].[ServiceUserAdd]
	@ServiceProviderID	int,
	@Name			nvarchar(128),
	@Description		nvarchar(256) = NULL,
	@AccountStatus		nvarchar(256) = NULL,
	@CreationDate		datetime = NULL,
	@LastLogonDate		datetime = NULL
AS
	INSERT INTO  dbo.ServiceUser (
		ServiceProviderID,
		[Name],
		Description,
		AccountStatus,
		CreationDate,
		LastLogonDate
	)
	VALUES (
		@ServiceProviderID,
		@Name,
		@Description,
		@AccountStatus,
		@CreationDate,
		@LastLogonDate
	)
	RETURN SCOPE_IDENTITY()
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ServiceUserBind]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ServiceUserBind]
GO
CREATE PROCEDURE [dbo].[ServiceUserBind]
	@ServiceProviderID	int,
	@Name			nvarchar(128),
	@Description		nvarchar(256) = NULL,
	@AccountStatus		nvarchar(256) = NULL,
	@CreationDate		datetime = NULL,
	@LastLogonDate		datetime = NULL
AS
	DECLARE	@ID	int

	SELECT	@ID = ServiceUserID
	FROM	[dbo].[ServiceUser]
	WHERE	ServiceProviderID = @ServiceProviderID
	  AND	[Name] = @Name

	IF @ID IS NULL
		EXEC @ID = ServiceUserAdd @ServiceProviderID,
			@Name,
			@Description,
			@AccountStatus,
			@CreationDate,
			@LastLogonDate

	RETURN @ID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ServiceUserSchema]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ServiceUserSchema]
GO
CREATE PROCEDURE [dbo].[ServiceUserSchema]
AS
	SELECT
	'IF OBJECT_ID(''tempdb..#ServiceUser'') IS NULL' + CAST(0x0A AS CHAR(1)) +
	'	CREATE TABLE #ServiceUser (' + CAST(0x0A AS CHAR(1)) +
	'		ServiceUserID		int NULL,' + CAST(0x0A AS CHAR(1)) +
	'		ServiceProviderID	int NOT NULL,' + CAST(0x0A AS CHAR(1)) +
	'		[Name]			nvarchar(128) COLLATE database_default NOT NULL,' + CAST(0x0A AS CHAR(1)) +
	'		Description		nvarchar(256) COLLATE database_default NULL,' + CAST(0x0A AS CHAR(1)) +
	'		AccountStatus		nvarchar(256) COLLATE database_default NULL,' + CAST(0x0A AS CHAR(1)) +
	'		CreationDate		datetime NULL,' + CAST(0x0A AS CHAR(1)) +
	'		LastLogonDate		datetime NULL' + CAST(0x0A AS CHAR(1)) +
	'	)' + CAST(0x0A AS CHAR(1)) +
	'ELSE' + CAST(0x0A AS CHAR(1)) +
	'	DELETE FROM #ServiceUser' + CAST(0x0A AS CHAR(1)) +
	'' AS SQL
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ServiceUserTempAdd]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ServiceUserTempAdd]
GO
CREATE PROCEDURE dbo.[ServiceUserTempAdd]
	@ServiceUserID		int,
	@ServiceProviderID	int,
	@Name			nvarchar(128),
	@Description		nvarchar(256) = NULL,
	@AccountStatus		nvarchar(256) = NULL,
	@CreationDate		datetime = NULL,
	@LastLogonDate		datetime = NULL
AS
	INSERT INTO #ServiceUser (
		ServiceUserID,
		ServiceProviderID,
		[Name],
		Description,
		AccountStatus,
		CreationDate,
		LastLogonDate
	)
	VALUES (
		@ServiceUserID,
		@ServiceProviderID,
		@Name,
		@Description,
		@AccountStatus,
		@CreationDate,
		@LastLogonDate
	)
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ServiceUserAddBatch]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ServiceUserAddBatch]
GO
CREATE PROCEDURE dbo.[ServiceUserAddBatch]
AS
	DECLARE @count int
	INSERT dbo.ServiceUser (
		ServiceProviderID,
		[Name],
		Description,
		AccountStatus,
		CreationDate,
		LastLogonDate
	)
		SELECT	ServiceProviderID,
			[Name],
			Description,
			AccountStatus,
			CreationDate,
			LastLogonDate
		FROM #ServiceUser
	SET @count = @@ROWCOUNT
	DROP TABLE #ServiceUser	-- Drop temporary table
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ServiceUserUpdateByID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ServiceUserUpdateByID]
GO
CREATE PROCEDURE [dbo].[ServiceUserUpdateByID]
	@ServiceUserID		int,
	@ServiceProviderID	int,
	@Name			nvarchar(128),
	@Description		nvarchar(256) = NULL,
	@AccountStatus		nvarchar(256) = NULL,
	@CreationDate		datetime = NULL,
	@LastLogonDate		datetime = NULL
AS
	DECLARE	@ID	int
	SET @ID = 0

	UPDATE	[dbo].[ServiceUser]
	SET	@ID = ServiceUserID,
		ServiceProviderID = @ServiceProviderID,
		[Name] = @Name,
		Description = @Description,
		AccountStatus = @AccountStatus,
		CreationDate = @CreationDate,
		LastLogonDate = @LastLogonDate
	WHERE	ServiceUserID = @ServiceUserID
	RETURN @ID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ServiceUserUpdateBatchByID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ServiceUserUpdateBatchByID]
GO
CREATE PROCEDURE dbo.[ServiceUserUpdateBatchByID]
AS
	DECLARE @count int

	CREATE INDEX [TempServiceUserID]
		ON #ServiceUser (ServiceUserID)

	UPDATE	[dbo].[ServiceUser]
	SET	ServiceProviderID = t.ServiceProviderID,
		[Name] = t.[Name],
		Description = t.Description,
		AccountStatus = t.AccountStatus,
		CreationDate = t.CreationDate,
		LastLogonDate = t.LastLogonDate
	FROM	#ServiceUser AS t
	WHERE	ServiceUser.ServiceUserID = t.ServiceUserID
	SET @count = @@ROWCOUNT
	DROP TABLE #ServiceUser	-- Drop the temporary table
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ServiceUserUpdateByServiceProviderIDName]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ServiceUserUpdateByServiceProviderIDName]
GO
CREATE PROCEDURE [dbo].[ServiceUserUpdateByServiceProviderIDName]
	@ServiceProviderID	int,
	@Name			nvarchar(128),
	@Description		nvarchar(256) = NULL,
	@AccountStatus		nvarchar(256) = NULL,
	@CreationDate		datetime = NULL,
	@LastLogonDate		datetime = NULL
AS
	DECLARE	@ID	int
	SET @ID = 0

	UPDATE	[dbo].[ServiceUser]
	SET	@ID = ServiceUserID,
		Description = @Description,
		AccountStatus = @AccountStatus,
		CreationDate = @CreationDate,
		LastLogonDate = @LastLogonDate
	WHERE	ServiceProviderID = @ServiceProviderID
	  AND	[Name] = @Name
	RETURN @ID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ServiceUserUpdateBatchByServiceProviderIDName]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ServiceUserUpdateBatchByServiceProviderIDName]
GO
CREATE PROCEDURE dbo.[ServiceUserUpdateBatchByServiceProviderIDName]
AS
	DECLARE @count int

	CREATE INDEX [TempServiceUserServiceProviderIDName]
		ON #ServiceUser (ServiceProviderID, [Name])

	UPDATE	[dbo].[ServiceUser]
	SET	Description = t.Description,
		AccountStatus = t.AccountStatus,
		CreationDate = t.CreationDate,
		LastLogonDate = t.LastLogonDate
	FROM	#ServiceUser AS t
	WHERE	ServiceUser.ServiceProviderID = t.ServiceProviderID
	  AND	ServiceUser.[Name] = t.[Name]
	SET @count = @@ROWCOUNT
	DROP TABLE #ServiceUser	-- Drop the temporary table
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ServiceUserPutByServiceProviderIDName]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ServiceUserPutByServiceProviderIDName]
GO
CREATE PROCEDURE [dbo].[ServiceUserPutByServiceProviderIDName]
	@ServiceProviderID	int,
	@Name			nvarchar(128),
	@Description		nvarchar(256) = NULL,
	@AccountStatus		nvarchar(256) = NULL,
	@CreationDate		datetime = NULL,
	@LastLogonDate		datetime = NULL
AS
	DECLARE @ID	int

	SELECT	@ID = ServiceUserID
	FROM	ServiceUser
	WHERE	ServiceProviderID = @ServiceProviderID
	  AND	[Name] = @Name

	IF @ID IS NULL
		EXEC @ID = ServiceUserAdd @ServiceProviderID,
			@Name,
			@Description,
			@AccountStatus,
			@CreationDate,
			@LastLogonDate
	ELSE
		EXEC ServiceUserUpdateByServiceProviderIDName @ServiceProviderID,
			@Name,
			@Description,
			@AccountStatus,
			@CreationDate,
			@LastLogonDate

	RETURN @ID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ServiceUserPutBatchByServiceProviderIDName]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ServiceUserPutBatchByServiceProviderIDName]
GO
CREATE PROCEDURE [dbo].[ServiceUserPutBatchByServiceProviderIDName]
AS
	DECLARE @count AS int
	SET @count = 0

	CREATE INDEX [TempServiceUserServiceProviderIDName]
		ON #ServiceUser (ServiceProviderID, [Name])

	BEGIN TRANSACTION
	UPDATE [dbo].[ServiceUser]
		SET	Description = t.Description,
			AccountStatus = t.AccountStatus,
			CreationDate = t.CreationDate,
			LastLogonDate = t.LastLogonDate
		FROM	#ServiceUser AS t
		WHERE	ServiceUser.ServiceProviderID = t.ServiceProviderID
		  AND	ServiceUser.[Name] = t.[Name]
	SET @count = @@ROWCOUNT

	INSERT [dbo].[ServiceUser] (
		ServiceProviderID,
		[Name],
		Description,
		AccountStatus,
		CreationDate,
		LastLogonDate
	)
		SELECT	ServiceProviderID,
			[Name],
			Description,
			AccountStatus,
			CreationDate,
			LastLogonDate
		FROM	#ServiceUser AS t
		WHERE NOT EXISTS(	-- Current record doesn't exist
			SELECT * FROM [dbo].[ServiceUser]
			WHERE	ServiceUser.ServiceProviderID = t.ServiceProviderID
			  AND	ServiceUser.[Name] = t.[Name]
		)
	SET @count = @count + @@ROWCOUNT
	DROP TABLE #ServiceUser	-- Drop the temporary table
	COMMIT WORK
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ServiceUserRemoveBatch]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ServiceUserRemoveBatch]
GO

CREATE PROCEDURE [dbo].[ServiceUserRemoveBatch]
AS

	CREATE INDEX [TempServiceUserServiceUserRemoveBatch]
		ON #ServiceUser (ServiceUserID)	

	-- Delete records from ServiceUser identified by fields of [TempServiceUserServiceUserRemoveBatch]
	DELETE [dbo].[ServiceUser]
	WHERE EXISTS(
			SELECT * FROM #ServiceUser AS t
			WHERE	ServiceUser.ServiceUserID = t.ServiceUserID
		)
	DROP TABLE #ServiceUser      -- Drop the temporary table
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ServiceUserRemoveByServiceProviderIDName]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ServiceUserRemoveByServiceProviderIDName]
GO
CREATE PROCEDURE [dbo].[ServiceUserRemoveByServiceProviderIDName]
	@ServiceProviderID	int,
	@Name			nvarchar(128)
AS
	-- ServiceUser deletes cascade to:
	--	ServiceUserOracle by FK_ServiceUserOracle_ServiceUser
	DELETE	[dbo].[ServiceUser]
	WHERE	ServiceProviderID = @ServiceProviderID
	  AND	[Name] = @Name
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ServiceUserRemoveAllByServiceProviderID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ServiceUserRemoveAllByServiceProviderID]
GO
CREATE PROCEDURE [dbo].[ServiceUserRemoveAllByServiceProviderID]
	@ServiceProviderID	int
AS
	DELETE	[dbo].[ServiceUser]
	WHERE	ServiceProviderID = @ServiceProviderID
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ServiceUserRemoveAll]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ServiceUserRemoveAll]
GO
CREATE PROCEDURE [dbo].[ServiceUserRemoveAll]
	
AS
	DELETE	[dbo].[ServiceUser]
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ServiceUserReplaceSubsetByServiceProviderID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ServiceUserReplaceSubsetByServiceProviderID]
GO
-- Replace the record subset selected by (@ServiceProviderID)
-- using unique identifier (ServiceProviderID, [Name])
-- updating fields (Description, AccountStatus, CreationDate, LastLogonDate)
CREATE PROCEDURE [dbo].[ServiceUserReplaceSubsetByServiceProviderID]
	@ServiceProviderID	int
AS
	DECLARE @count AS int
	SET @count = 0

	CREATE INDEX [TempServiceUserByServiceProviderID]
		ON #ServiceUser (ServiceProviderID, [Name])

	BEGIN TRANSACTION
	DELETE [ServiceUser]
		WHERE	ServiceProviderID = @ServiceProviderID
		AND NOT EXISTS(		-- Replacement record doesn't exist
			SELECT * FROM #ServiceUser AS t
			WHERE	ServiceUser.ServiceProviderID = t.ServiceProviderID
			  AND	ServiceUser.[Name] = t.[Name]
		)

	UPDATE [dbo].[ServiceUser]
		SET	Description = t.Description,
			AccountStatus = t.AccountStatus,
			CreationDate = t.CreationDate,
			LastLogonDate = t.LastLogonDate
		FROM	#ServiceUser AS t
		WHERE	ServiceUser.ServiceProviderID = t.ServiceProviderID
		  AND	ServiceUser.[Name] = t.[Name]
	SET @count = @@ROWCOUNT

	INSERT [ServiceUser] (
		ServiceProviderID,
		[Name],
		Description,
		AccountStatus,
		CreationDate,
		LastLogonDate
	)
		SELECT	ServiceProviderID,
			[Name],
			Description,
			AccountStatus,
			CreationDate,
			LastLogonDate
		FROM	#ServiceUser AS t
		WHERE NOT EXISTS(	-- Current record doesn't exist
			SELECT * FROM [ServiceUser]
			WHERE	ServiceUser.ServiceProviderID = t.ServiceProviderID
			  AND	ServiceUser.[Name] = t.[Name]
		)
	SET @count = @count + @@ROWCOUNT
	DROP TABLE #ServiceUser	-- Drop the temporary table
	COMMIT WORK
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ServiceUserOracleGetByServiceUserID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ServiceUserOracleGetByServiceUserID]
GO
CREATE PROCEDURE [dbo].[ServiceUserOracleGetByServiceUserID]
	@ServiceUserID		int
AS
	SELECT	ServiceUserOracleID,
		ServiceUserID,
		DefaultTablespace,
		TempTablespace
	FROM	[dbo].[ServiceUserOracle]
	WHERE	ServiceUserID = @ServiceUserID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ServiceUserOracleGetByID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ServiceUserOracleGetByID]
GO
CREATE PROCEDURE [dbo].[ServiceUserOracleGetByID]
	@ServiceUserOracleID	int
AS
	SELECT	ServiceUserOracleID,
		ServiceUserID,
		DefaultTablespace,
		TempTablespace
	FROM	[dbo].[ServiceUserOracle]
	WHERE	ServiceUserOracleID = @ServiceUserOracleID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ServiceUserOracleGetAll]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ServiceUserOracleGetAll]
GO
CREATE PROCEDURE [dbo].[ServiceUserOracleGetAll]
AS
	SELECT	ServiceUserOracleID,
		ServiceUserID,
		DefaultTablespace,
		TempTablespace
	FROM	[dbo].[ServiceUserOracle]
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ServiceUserOracleAdd]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ServiceUserOracleAdd]
GO
CREATE PROCEDURE [dbo].[ServiceUserOracleAdd]
	@ServiceUserID		int,
	@DefaultTablespace	nvarchar(256) = NULL,
	@TempTablespace		nvarchar(256) = NULL
AS
	INSERT INTO  dbo.ServiceUserOracle (
		ServiceUserID,
		DefaultTablespace,
		TempTablespace
	)
	VALUES (
		@ServiceUserID,
		@DefaultTablespace,
		@TempTablespace
	)
	RETURN SCOPE_IDENTITY()
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ServiceUserOracleBind]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ServiceUserOracleBind]
GO
CREATE PROCEDURE [dbo].[ServiceUserOracleBind]
	@ServiceUserID		int,
	@DefaultTablespace	nvarchar(256) = NULL,
	@TempTablespace		nvarchar(256) = NULL
AS
	DECLARE	@ID	int

	SELECT	@ID = ServiceUserOracleID
	FROM	[dbo].[ServiceUserOracle]
	WHERE	ServiceUserID = @ServiceUserID

	IF @ID IS NULL
		EXEC @ID = ServiceUserOracleAdd @ServiceUserID,
			@DefaultTablespace,
			@TempTablespace

	RETURN @ID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ServiceUserOracleSchema]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ServiceUserOracleSchema]
GO
CREATE PROCEDURE [dbo].[ServiceUserOracleSchema]
AS
	SELECT
	'IF OBJECT_ID(''tempdb..#ServiceUserOracle'') IS NULL' + CAST(0x0A AS CHAR(1)) +
	'	CREATE TABLE #ServiceUserOracle (' + CAST(0x0A AS CHAR(1)) +
	'		ServiceUserOracleID	int NULL,' + CAST(0x0A AS CHAR(1)) +
	'		ServiceUserID		int NOT NULL,' + CAST(0x0A AS CHAR(1)) +
	'		DefaultTablespace	nvarchar(256) COLLATE database_default NULL,' + CAST(0x0A AS CHAR(1)) +
	'		TempTablespace		nvarchar(256) COLLATE database_default NULL' + CAST(0x0A AS CHAR(1)) +
	'	)' + CAST(0x0A AS CHAR(1)) +
	'ELSE' + CAST(0x0A AS CHAR(1)) +
	'	DELETE FROM #ServiceUserOracle' + CAST(0x0A AS CHAR(1)) +
	'' AS SQL
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ServiceUserOracleTempAdd]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ServiceUserOracleTempAdd]
GO
CREATE PROCEDURE dbo.[ServiceUserOracleTempAdd]
	@ServiceUserOracleID	int,
	@ServiceUserID		int,
	@DefaultTablespace	nvarchar(256) = NULL,
	@TempTablespace		nvarchar(256) = NULL
AS
	INSERT INTO #ServiceUserOracle (
		ServiceUserOracleID,
		ServiceUserID,
		DefaultTablespace,
		TempTablespace
	)
	VALUES (
		@ServiceUserOracleID,
		@ServiceUserID,
		@DefaultTablespace,
		@TempTablespace
	)
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ServiceUserOracleAddBatch]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ServiceUserOracleAddBatch]
GO
CREATE PROCEDURE dbo.[ServiceUserOracleAddBatch]
AS
	DECLARE @count int
	INSERT dbo.ServiceUserOracle (
		ServiceUserID,
		DefaultTablespace,
		TempTablespace
	)
		SELECT	ServiceUserID,
			DefaultTablespace,
			TempTablespace
		FROM #ServiceUserOracle
	SET @count = @@ROWCOUNT
	DROP TABLE #ServiceUserOracle	-- Drop temporary table
	RETURN @count
GO

/*
Add new ServiceUserOracle bound to
	ServiceUser using ServiceProviderID, Name
	with DefaultTablespace, TempTablespace
*/

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ServiceUserOracleUpdateByID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ServiceUserOracleUpdateByID]
GO
CREATE PROCEDURE [dbo].[ServiceUserOracleUpdateByID]
	@ServiceUserOracleID	int,
	@ServiceUserID		int,
	@DefaultTablespace	nvarchar(256) = NULL,
	@TempTablespace		nvarchar(256) = NULL
AS
	DECLARE	@ID	int
	SET @ID = 0

	UPDATE	[dbo].[ServiceUserOracle]
	SET	@ID = ServiceUserOracleID,
		ServiceUserID = @ServiceUserID,
		DefaultTablespace = @DefaultTablespace,
		TempTablespace = @TempTablespace
	WHERE	ServiceUserOracleID = @ServiceUserOracleID
	RETURN @ID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ServiceUserOracleUpdateBatchByID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ServiceUserOracleUpdateBatchByID]
GO
CREATE PROCEDURE dbo.[ServiceUserOracleUpdateBatchByID]
AS
	DECLARE @count int

	CREATE INDEX [TempServiceUserOracleID]
		ON #ServiceUserOracle (ServiceUserOracleID)

	UPDATE	[dbo].[ServiceUserOracle]
	SET	ServiceUserID = t.ServiceUserID,
		DefaultTablespace = t.DefaultTablespace,
		TempTablespace = t.TempTablespace
	FROM	#ServiceUserOracle AS t
	WHERE	ServiceUserOracle.ServiceUserOracleID = t.ServiceUserOracleID
	SET @count = @@ROWCOUNT
	DROP TABLE #ServiceUserOracle	-- Drop the temporary table
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ServiceUserOracleUpdateByServiceUserID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ServiceUserOracleUpdateByServiceUserID]
GO
CREATE PROCEDURE [dbo].[ServiceUserOracleUpdateByServiceUserID]
	@ServiceUserID		int,
	@DefaultTablespace	nvarchar(256) = NULL,
	@TempTablespace		nvarchar(256) = NULL
AS
	DECLARE	@ID	int
	SET @ID = 0

	UPDATE	[dbo].[ServiceUserOracle]
	SET	@ID = ServiceUserOracleID,
		DefaultTablespace = @DefaultTablespace,
		TempTablespace = @TempTablespace
	WHERE	ServiceUserID = @ServiceUserID
	RETURN @ID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ServiceUserOracleUpdateBatchByServiceUserID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ServiceUserOracleUpdateBatchByServiceUserID]
GO
CREATE PROCEDURE dbo.[ServiceUserOracleUpdateBatchByServiceUserID]
AS
	DECLARE @count int

	CREATE INDEX [TempServiceUserOracleServiceUserID]
		ON #ServiceUserOracle (ServiceUserID)

	UPDATE	[dbo].[ServiceUserOracle]
	SET	DefaultTablespace = t.DefaultTablespace,
		TempTablespace = t.TempTablespace
	FROM	#ServiceUserOracle AS t
	WHERE	ServiceUserOracle.ServiceUserID = t.ServiceUserID
	SET @count = @@ROWCOUNT
	DROP TABLE #ServiceUserOracle	-- Drop the temporary table
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ServiceUserOraclePutByServiceUserID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ServiceUserOraclePutByServiceUserID]
GO
CREATE PROCEDURE [dbo].[ServiceUserOraclePutByServiceUserID]
	@ServiceUserID		int,
	@DefaultTablespace	nvarchar(256) = NULL,
	@TempTablespace		nvarchar(256) = NULL
AS
	DECLARE @ID	int

	SELECT	@ID = ServiceUserOracleID
	FROM	ServiceUserOracle
	WHERE	ServiceUserID = @ServiceUserID

	IF @ID IS NULL
		EXEC @ID = ServiceUserOracleAdd @ServiceUserID,
			@DefaultTablespace,
			@TempTablespace
	ELSE
		EXEC ServiceUserOracleUpdateByServiceUserID @ServiceUserID,
			@DefaultTablespace,
			@TempTablespace

	RETURN @ID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ServiceUserOraclePutBatchByServiceUserID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ServiceUserOraclePutBatchByServiceUserID]
GO
CREATE PROCEDURE [dbo].[ServiceUserOraclePutBatchByServiceUserID]
AS
	DECLARE @count AS int
	SET @count = 0

	CREATE INDEX [TempServiceUserOracleServiceUserID]
		ON #ServiceUserOracle (ServiceUserID)

	BEGIN TRANSACTION
	UPDATE [dbo].[ServiceUserOracle]
		SET	DefaultTablespace = t.DefaultTablespace,
			TempTablespace = t.TempTablespace
		FROM	#ServiceUserOracle AS t
		WHERE	ServiceUserOracle.ServiceUserID = t.ServiceUserID
	SET @count = @@ROWCOUNT

	INSERT [dbo].[ServiceUserOracle] (
		ServiceUserID,
		DefaultTablespace,
		TempTablespace
	)
		SELECT	ServiceUserID,
			DefaultTablespace,
			TempTablespace
		FROM	#ServiceUserOracle AS t
		WHERE NOT EXISTS(	-- Current record doesn't exist
			SELECT * FROM [dbo].[ServiceUserOracle]
			WHERE	ServiceUserOracle.ServiceUserID = t.ServiceUserID
		)
	SET @count = @count + @@ROWCOUNT
	DROP TABLE #ServiceUserOracle	-- Drop the temporary table
	COMMIT WORK
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ServiceUserOracleRemoveBatch]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ServiceUserOracleRemoveBatch]
GO

CREATE PROCEDURE [dbo].[ServiceUserOracleRemoveBatch]
AS

	CREATE INDEX [TempServiceUserOracleServiceUserOracleRemoveBatch]
		ON #ServiceUserOracle (ServiceUserOracleID)	

	-- Delete records from ServiceUserOracle identified by fields of [TempServiceUserOracleServiceUserOracleRemoveBatch]
	DELETE [dbo].[ServiceUserOracle]
	WHERE EXISTS(
			SELECT * FROM #ServiceUserOracle AS t
			WHERE	ServiceUserOracle.ServiceUserOracleID = t.ServiceUserOracleID
		)
	DROP TABLE #ServiceUserOracle      -- Drop the temporary table
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ServiceUserOracleRemoveByServiceUserID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ServiceUserOracleRemoveByServiceUserID]
GO
CREATE PROCEDURE [dbo].[ServiceUserOracleRemoveByServiceUserID]
	@ServiceUserID		int
AS
	DELETE	[dbo].[ServiceUserOracle]
	WHERE	ServiceUserID = @ServiceUserID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ServiceUserOracleRemoveAll]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ServiceUserOracleRemoveAll]
GO
CREATE PROCEDURE [dbo].[ServiceUserOracleRemoveAll]
	
AS
	DELETE	[dbo].[ServiceUserOracle]
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ServiceProviderApplicationOracleGetByID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ServiceProviderApplicationOracleGetByID]
GO
CREATE PROCEDURE [dbo].[ServiceProviderApplicationOracleGetByID]
	@ServiceProviderApplicationOracleID int
AS
	SELECT	ServiceProviderApplicationOracleID,
		ServiceProviderID,
		[Name],
		Users,
		ApplicationID
	FROM	[dbo].[ServiceProviderApplicationOracle]
	WHERE	ServiceProviderApplicationOracleID = @ServiceProviderApplicationOracleID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ServiceProviderApplicationOracleGetAll]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ServiceProviderApplicationOracleGetAll]
GO
CREATE PROCEDURE [dbo].[ServiceProviderApplicationOracleGetAll]
AS
	SELECT	ServiceProviderApplicationOracleID,
		ServiceProviderID,
		[Name],
		Users,
		ApplicationID
	FROM	[dbo].[ServiceProviderApplicationOracle]
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ServiceProviderApplicationOracleAdd]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ServiceProviderApplicationOracleAdd]
GO
CREATE PROCEDURE [dbo].[ServiceProviderApplicationOracleAdd]
	@ServiceProviderID	int,
	@Name			nvarchar(240),
	@Users			int,
	@ApplicationID		int
AS
	INSERT INTO  dbo.ServiceProviderApplicationOracle (
		ServiceProviderID,
		[Name],
		Users,
		ApplicationID
	)
	VALUES (
		@ServiceProviderID,
		@Name,
		@Users,
		@ApplicationID
	)
	RETURN SCOPE_IDENTITY()
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ServiceProviderApplicationOracleSchema]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ServiceProviderApplicationOracleSchema]
GO
CREATE PROCEDURE [dbo].[ServiceProviderApplicationOracleSchema]
AS
	SELECT
	'IF OBJECT_ID(''tempdb..#ServiceProviderApplicationOracle'') IS NULL' + CAST(0x0A AS CHAR(1)) +
	'	CREATE TABLE #ServiceProviderApplicationOracle (' + CAST(0x0A AS CHAR(1)) +
	'		ServiceProviderApplicationOracleID int NULL,' + CAST(0x0A AS CHAR(1)) +
	'		ServiceProviderID	int NOT NULL,' + CAST(0x0A AS CHAR(1)) +
	'		[Name]			nvarchar(240) COLLATE database_default NOT NULL,' + CAST(0x0A AS CHAR(1)) +
	'		Users			int NOT NULL,' + CAST(0x0A AS CHAR(1)) +
	'		ApplicationID		int NOT NULL' + CAST(0x0A AS CHAR(1)) +
	'	)' + CAST(0x0A AS CHAR(1)) +
	'ELSE' + CAST(0x0A AS CHAR(1)) +
	'	DELETE FROM #ServiceProviderApplicationOracle' + CAST(0x0A AS CHAR(1)) +
	'' AS SQL
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ServiceProviderApplicationOracleTempAdd]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ServiceProviderApplicationOracleTempAdd]
GO
CREATE PROCEDURE dbo.[ServiceProviderApplicationOracleTempAdd]
	@ServiceProviderApplicationOracleID int,
	@ServiceProviderID	int,
	@Name			nvarchar(240),
	@Users			int,
	@ApplicationID		int
AS
	INSERT INTO #ServiceProviderApplicationOracle (
		ServiceProviderApplicationOracleID,
		ServiceProviderID,
		[Name],
		Users,
		ApplicationID
	)
	VALUES (
		@ServiceProviderApplicationOracleID,
		@ServiceProviderID,
		@Name,
		@Users,
		@ApplicationID
	)
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ServiceProviderApplicationOracleAddBatch]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ServiceProviderApplicationOracleAddBatch]
GO
CREATE PROCEDURE dbo.[ServiceProviderApplicationOracleAddBatch]
AS
	DECLARE @count int
	INSERT dbo.ServiceProviderApplicationOracle (
		ServiceProviderID,
		[Name],
		Users,
		ApplicationID
	)
		SELECT	ServiceProviderID,
			[Name],
			Users,
			ApplicationID
		FROM #ServiceProviderApplicationOracle
	SET @count = @@ROWCOUNT
	DROP TABLE #ServiceProviderApplicationOracle	-- Drop temporary table
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ServiceProviderApplicationOracleUpdateByID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ServiceProviderApplicationOracleUpdateByID]
GO
CREATE PROCEDURE [dbo].[ServiceProviderApplicationOracleUpdateByID]
	@ServiceProviderApplicationOracleID int,
	@ServiceProviderID	int,
	@Name			nvarchar(240),
	@Users			int,
	@ApplicationID		int
AS
	DECLARE	@ID	int
	SET @ID = 0

	UPDATE	[dbo].[ServiceProviderApplicationOracle]
	SET	@ID = ServiceProviderApplicationOracleID,
		ServiceProviderID = @ServiceProviderID,
		[Name] = @Name,
		Users = @Users,
		ApplicationID = @ApplicationID
	WHERE	ServiceProviderApplicationOracleID = @ServiceProviderApplicationOracleID
	RETURN @ID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ServiceProviderApplicationOracleUpdateBatchByID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ServiceProviderApplicationOracleUpdateBatchByID]
GO
CREATE PROCEDURE dbo.[ServiceProviderApplicationOracleUpdateBatchByID]
AS
	DECLARE @count int

	CREATE INDEX [TempServiceProviderApplicationOracleID]
		ON #ServiceProviderApplicationOracle (ServiceProviderApplicationOracleID)

	UPDATE	[dbo].[ServiceProviderApplicationOracle]
	SET	ServiceProviderID = t.ServiceProviderID,
		[Name] = t.[Name],
		Users = t.Users,
		ApplicationID = t.ApplicationID
	FROM	#ServiceProviderApplicationOracle AS t
	WHERE	ServiceProviderApplicationOracle.ServiceProviderApplicationOracleID = t.ServiceProviderApplicationOracleID
	SET @count = @@ROWCOUNT
	DROP TABLE #ServiceProviderApplicationOracle	-- Drop the temporary table
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ServiceProviderApplicationOracleRemoveBatch]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ServiceProviderApplicationOracleRemoveBatch]
GO

CREATE PROCEDURE [dbo].[ServiceProviderApplicationOracleRemoveBatch]
AS

	CREATE INDEX [TempServiceProviderApplicationOracleServiceProviderApplicationOracleRemoveBatch]
		ON #ServiceProviderApplicationOracle (ServiceProviderApplicationOracleID)	

	-- Delete records from ServiceProviderApplicationOracle identified by fields of [TempServiceProviderApplicationOracleServiceProviderApplicationOracleRemoveBatch]
	DELETE [dbo].[ServiceProviderApplicationOracle]
	WHERE EXISTS(
			SELECT * FROM #ServiceProviderApplicationOracle AS t
			WHERE	ServiceProviderApplicationOracle.ServiceProviderApplicationOracleID = t.ServiceProviderApplicationOracleID
		)
	DROP TABLE #ServiceProviderApplicationOracle      -- Drop the temporary table
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ServiceProviderApplicationOracleRemoveByID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ServiceProviderApplicationOracleRemoveByID]
GO
CREATE PROCEDURE [dbo].[ServiceProviderApplicationOracleRemoveByID]
	@ServiceProviderApplicationOracleID int
AS
	-- ServiceProviderApplicationOracle deletes cascade to:
	--	ServiceProviderApplicationUserOracle by FK_ServiceProviderApplicationUserOracle_Application
	DELETE	[dbo].[ServiceProviderApplicationOracle]
	WHERE	ServiceProviderApplicationOracleID = @ServiceProviderApplicationOracleID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ServiceProviderApplicationOracleRemoveAll]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ServiceProviderApplicationOracleRemoveAll]
GO
CREATE PROCEDURE [dbo].[ServiceProviderApplicationOracleRemoveAll]
	
AS
	DELETE	[dbo].[ServiceProviderApplicationOracle]
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ServiceProviderApplicationUserOracleGetByID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ServiceProviderApplicationUserOracleGetByID]
GO
CREATE PROCEDURE [dbo].[ServiceProviderApplicationUserOracleGetByID]
	@ServiceProviderApplicationUserOracleID int
AS
	SELECT	ServiceProviderApplicationUserOracleID,
		ServiceProviderApplicationOracleID,
		UserID,
		UserName,
		Description,
		EMail
	FROM	[dbo].[ServiceProviderApplicationUserOracle]
	WHERE	ServiceProviderApplicationUserOracleID = @ServiceProviderApplicationUserOracleID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ServiceProviderApplicationUserOracleGetAll]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ServiceProviderApplicationUserOracleGetAll]
GO
CREATE PROCEDURE [dbo].[ServiceProviderApplicationUserOracleGetAll]
AS
	SELECT	ServiceProviderApplicationUserOracleID,
		ServiceProviderApplicationOracleID,
		UserID,
		UserName,
		Description,
		EMail
	FROM	[dbo].[ServiceProviderApplicationUserOracle]
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ServiceProviderApplicationUserOracleAdd]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ServiceProviderApplicationUserOracleAdd]
GO
CREATE PROCEDURE [dbo].[ServiceProviderApplicationUserOracleAdd]
	@ServiceProviderApplicationOracleID int,
	@UserID			int,
	@UserName		nvarchar(100),
	@Description		nvarchar(240) = NULL,
	@EMail			nvarchar(240) = NULL
AS
	INSERT INTO  dbo.ServiceProviderApplicationUserOracle (
		ServiceProviderApplicationOracleID,
		UserID,
		UserName,
		Description,
		EMail
	)
	VALUES (
		@ServiceProviderApplicationOracleID,
		@UserID,
		@UserName,
		@Description,
		@EMail
	)
	RETURN SCOPE_IDENTITY()
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ServiceProviderApplicationUserOracleSchema]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ServiceProviderApplicationUserOracleSchema]
GO
CREATE PROCEDURE [dbo].[ServiceProviderApplicationUserOracleSchema]
AS
	SELECT
	'IF OBJECT_ID(''tempdb..#ServiceProviderApplicationUserOracle'') IS NULL' + CAST(0x0A AS CHAR(1)) +
	'	CREATE TABLE #ServiceProviderApplicationUserOracle (' + CAST(0x0A AS CHAR(1)) +
	'		ServiceProviderApplicationUserOracleID int NULL,' + CAST(0x0A AS CHAR(1)) +
	'		ServiceProviderApplicationOracleID int NOT NULL,' + CAST(0x0A AS CHAR(1)) +
	'		UserID			int NOT NULL,' + CAST(0x0A AS CHAR(1)) +
	'		UserName		nvarchar(100) COLLATE database_default NOT NULL,' + CAST(0x0A AS CHAR(1)) +
	'		Description		nvarchar(240) COLLATE database_default NULL,' + CAST(0x0A AS CHAR(1)) +
	'		EMail			nvarchar(240) COLLATE database_default NULL' + CAST(0x0A AS CHAR(1)) +
	'	)' + CAST(0x0A AS CHAR(1)) +
	'ELSE' + CAST(0x0A AS CHAR(1)) +
	'	DELETE FROM #ServiceProviderApplicationUserOracle' + CAST(0x0A AS CHAR(1)) +
	'' AS SQL
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ServiceProviderApplicationUserOracleTempAdd]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ServiceProviderApplicationUserOracleTempAdd]
GO
CREATE PROCEDURE dbo.[ServiceProviderApplicationUserOracleTempAdd]
	@ServiceProviderApplicationUserOracleID int,
	@ServiceProviderApplicationOracleID int,
	@UserID			int,
	@UserName		nvarchar(100),
	@Description		nvarchar(240) = NULL,
	@EMail			nvarchar(240) = NULL
AS
	INSERT INTO #ServiceProviderApplicationUserOracle (
		ServiceProviderApplicationUserOracleID,
		ServiceProviderApplicationOracleID,
		UserID,
		UserName,
		Description,
		EMail
	)
	VALUES (
		@ServiceProviderApplicationUserOracleID,
		@ServiceProviderApplicationOracleID,
		@UserID,
		@UserName,
		@Description,
		@EMail
	)
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ServiceProviderApplicationUserOracleAddBatch]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ServiceProviderApplicationUserOracleAddBatch]
GO
CREATE PROCEDURE dbo.[ServiceProviderApplicationUserOracleAddBatch]
AS
	DECLARE @count int
	INSERT dbo.ServiceProviderApplicationUserOracle (
		ServiceProviderApplicationOracleID,
		UserID,
		UserName,
		Description,
		EMail
	)
		SELECT	ServiceProviderApplicationOracleID,
			UserID,
			UserName,
			Description,
			EMail
		FROM #ServiceProviderApplicationUserOracle
	SET @count = @@ROWCOUNT
	DROP TABLE #ServiceProviderApplicationUserOracle	-- Drop temporary table
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ServiceProviderApplicationUserOracleUpdateByID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ServiceProviderApplicationUserOracleUpdateByID]
GO
CREATE PROCEDURE [dbo].[ServiceProviderApplicationUserOracleUpdateByID]
	@ServiceProviderApplicationUserOracleID int,
	@ServiceProviderApplicationOracleID int,
	@UserID			int,
	@UserName		nvarchar(100),
	@Description		nvarchar(240) = NULL,
	@EMail			nvarchar(240) = NULL
AS
	DECLARE	@ID	int
	SET @ID = 0

	UPDATE	[dbo].[ServiceProviderApplicationUserOracle]
	SET	@ID = ServiceProviderApplicationUserOracleID,
		ServiceProviderApplicationOracleID = @ServiceProviderApplicationOracleID,
		UserID = @UserID,
		UserName = @UserName,
		Description = @Description,
		EMail = @EMail
	WHERE	ServiceProviderApplicationUserOracleID = @ServiceProviderApplicationUserOracleID
	RETURN @ID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ServiceProviderApplicationUserOracleUpdateBatchByID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ServiceProviderApplicationUserOracleUpdateBatchByID]
GO
CREATE PROCEDURE dbo.[ServiceProviderApplicationUserOracleUpdateBatchByID]
AS
	DECLARE @count int

	CREATE INDEX [TempServiceProviderApplicationUserOracleID]
		ON #ServiceProviderApplicationUserOracle (ServiceProviderApplicationUserOracleID)

	UPDATE	[dbo].[ServiceProviderApplicationUserOracle]
	SET	ServiceProviderApplicationOracleID = t.ServiceProviderApplicationOracleID,
		UserID = t.UserID,
		UserName = t.UserName,
		Description = t.Description,
		EMail = t.EMail
	FROM	#ServiceProviderApplicationUserOracle AS t
	WHERE	ServiceProviderApplicationUserOracle.ServiceProviderApplicationUserOracleID = t.ServiceProviderApplicationUserOracleID
	SET @count = @@ROWCOUNT
	DROP TABLE #ServiceProviderApplicationUserOracle	-- Drop the temporary table
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ServiceProviderApplicationUserOracleRemoveBatch]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ServiceProviderApplicationUserOracleRemoveBatch]
GO

CREATE PROCEDURE [dbo].[ServiceProviderApplicationUserOracleRemoveBatch]
AS

	CREATE INDEX [TempServiceProviderApplicationUserOracleServiceProviderApplicationUserOracleRemoveBatch]
		ON #ServiceProviderApplicationUserOracle (ServiceProviderApplicationUserOracleID)	

	-- Delete records from ServiceProviderApplicationUserOracle identified by fields of [TempServiceProviderApplicationUserOracleServiceProviderApplicationUserOracleRemoveBatch]
	DELETE [dbo].[ServiceProviderApplicationUserOracle]
	WHERE EXISTS(
			SELECT * FROM #ServiceProviderApplicationUserOracle AS t
			WHERE	ServiceProviderApplicationUserOracle.ServiceProviderApplicationUserOracleID = t.ServiceProviderApplicationUserOracleID
		)
	DROP TABLE #ServiceProviderApplicationUserOracle      -- Drop the temporary table
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ServiceProviderApplicationUserOracleRemoveByID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ServiceProviderApplicationUserOracleRemoveByID]
GO
CREATE PROCEDURE [dbo].[ServiceProviderApplicationUserOracleRemoveByID]
	@ServiceProviderApplicationUserOracleID int
AS
	DELETE	[dbo].[ServiceProviderApplicationUserOracle]
	WHERE	ServiceProviderApplicationUserOracleID = @ServiceProviderApplicationUserOracleID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ServiceProviderApplicationUserOracleRemoveAll]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ServiceProviderApplicationUserOracleRemoveAll]
GO
CREATE PROCEDURE [dbo].[ServiceProviderApplicationUserOracleRemoveAll]
	
AS
	DELETE	[dbo].[ServiceProviderApplicationUserOracle]
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[DistributionServerTypeGetByID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[DistributionServerTypeGetByID]
GO
CREATE PROCEDURE [dbo].[DistributionServerTypeGetByID]
	@DistributionServerTypeID int
AS
	SELECT	DistributionServerTypeID,
		DistributionServerTypeName
	FROM	[dbo].[DistributionServerType]
	WHERE	DistributionServerTypeID = @DistributionServerTypeID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[DistributionServerTypeGetByName]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[DistributionServerTypeGetByName]
GO
CREATE PROCEDURE [dbo].[DistributionServerTypeGetByName]
	@DistributionServerTypeName nvarchar(256)
AS
	SELECT	DistributionServerTypeID,
		DistributionServerTypeName
	FROM	[dbo].[DistributionServerType]
	WHERE	DistributionServerTypeName = @DistributionServerTypeName
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[DistributionServerTypeGetAll]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[DistributionServerTypeGetAll]
GO
CREATE PROCEDURE [dbo].[DistributionServerTypeGetAll]
AS
	SELECT	DistributionServerTypeID,
		DistributionServerTypeName
	FROM	[dbo].[DistributionServerType]
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[DistributionServerGetByServerUID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[DistributionServerGetByServerUID]
GO
CREATE PROCEDURE [dbo].[DistributionServerGetByServerUID]
	@ServerUID		binary(16)
AS
	SELECT	ServerUID,
		DNSName,
		ServerType,
		ServerName,
		PrimaryParentUID,
		ConfigState,
		LastConfigStart,
		LastConfigJobId,
		ConfigFailReason,
		PolicyQuarantined
	FROM	[dbo].[DistributionServer]
	WHERE	ServerUID = @ServerUID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[DistributionServerGetAll]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[DistributionServerGetAll]
GO
CREATE PROCEDURE [dbo].[DistributionServerGetAll]
AS
	SELECT	ServerUID,
		DNSName,
		ServerType,
		ServerName,
		PrimaryParentUID,
		ConfigState,
		LastConfigStart,
		LastConfigJobId,
		ConfigFailReason,
		PolicyQuarantined
	FROM	[dbo].[DistributionServer]
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[DistributionServerAdd]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[DistributionServerAdd]
GO
CREATE PROCEDURE [dbo].[DistributionServerAdd]
	@ServerUID		binary(16),
	@DNSName		nvarchar(128) = NULL,
	@ServerType		smallint = 0,
	@ServerName		nvarchar(64),
	@PrimaryParentUID	binary(16) = NULL,
	@ConfigState		nvarchar(20) = NULL,
	@LastConfigStart	datetime = NULL,
	@LastConfigJobId	nvarchar(40) = NULL,
	@ConfigFailReason	ntext = NULL,
	@PolicyQuarantined	bit = 0
AS
	INSERT INTO  dbo.DistributionServer (
		ServerUID,
		DNSName,
		ServerType,
		ServerName,
		PrimaryParentUID,
		ConfigState,
		LastConfigStart,
		LastConfigJobId,
		ConfigFailReason,
		PolicyQuarantined
	)
	VALUES (
		@ServerUID,
		@DNSName,
		@ServerType,
		@ServerName,
		@PrimaryParentUID,
		@ConfigState,
		@LastConfigStart,
		@LastConfigJobId,
		@ConfigFailReason,
		@PolicyQuarantined
	)
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[DistributionServerSchema]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[DistributionServerSchema]
GO
CREATE PROCEDURE [dbo].[DistributionServerSchema]
AS
	SELECT
	'IF OBJECT_ID(''tempdb..#DistributionServer'') IS NULL' + CAST(0x0A AS CHAR(1)) +
	'	CREATE TABLE #DistributionServer (' + CAST(0x0A AS CHAR(1)) +
	'		ServerUID		binary(16) NOT NULL,' + CAST(0x0A AS CHAR(1)) +
	'		DNSName			nvarchar(128) COLLATE database_default NULL,' + CAST(0x0A AS CHAR(1)) +
	'		ServerType		smallint NOT NULL DEFAULT 0,' + CAST(0x0A AS CHAR(1)) +
	'		ServerName		nvarchar(64) COLLATE database_default NOT NULL,' + CAST(0x0A AS CHAR(1)) +
	'		PrimaryParentUID	binary(16) NULL,' + CAST(0x0A AS CHAR(1)) +
	'		ConfigState		nvarchar(20) COLLATE database_default NULL,' + CAST(0x0A AS CHAR(1)) +
	'		LastConfigStart		datetime NULL,' + CAST(0x0A AS CHAR(1)) +
	'		LastConfigJobId		nvarchar(40) COLLATE database_default NULL,' + CAST(0x0A AS CHAR(1)) +
	'		ConfigFailReason	ntext COLLATE database_default NULL,' + CAST(0x0A AS CHAR(1)) +
	'		PolicyQuarantined	bit NOT NULL DEFAULT 0' + CAST(0x0A AS CHAR(1)) +
	'	)' + CAST(0x0A AS CHAR(1)) +
	'ELSE' + CAST(0x0A AS CHAR(1)) +
	'	DELETE FROM #DistributionServer' + CAST(0x0A AS CHAR(1)) +
	'' AS SQL
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[DistributionServerTempAdd]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[DistributionServerTempAdd]
GO
CREATE PROCEDURE dbo.[DistributionServerTempAdd]
	@ServerUID		binary(16),
	@DNSName		nvarchar(128) = NULL,
	@ServerType		smallint = 0,
	@ServerName		nvarchar(64),
	@PrimaryParentUID	binary(16) = NULL,
	@ConfigState		nvarchar(20) = NULL,
	@LastConfigStart	datetime = NULL,
	@LastConfigJobId	nvarchar(40) = NULL,
	@ConfigFailReason	ntext = NULL,
	@PolicyQuarantined	bit = 0
AS
	INSERT INTO #DistributionServer (
		ServerUID,
		DNSName,
		ServerType,
		ServerName,
		PrimaryParentUID,
		ConfigState,
		LastConfigStart,
		LastConfigJobId,
		ConfigFailReason,
		PolicyQuarantined
	)
	VALUES (
		@ServerUID,
		@DNSName,
		@ServerType,
		@ServerName,
		@PrimaryParentUID,
		@ConfigState,
		@LastConfigStart,
		@LastConfigJobId,
		@ConfigFailReason,
		@PolicyQuarantined
	)
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[DistributionServerAddBatch]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[DistributionServerAddBatch]
GO
CREATE PROCEDURE dbo.[DistributionServerAddBatch]
AS
	DECLARE @count int
	INSERT dbo.DistributionServer (
		ServerUID,
		DNSName,
		ServerType,
		ServerName,
		PrimaryParentUID,
		ConfigState,
		LastConfigStart,
		LastConfigJobId,
		ConfigFailReason,
		PolicyQuarantined
	)
		SELECT	ServerUID,
			DNSName,
			ServerType,
			ServerName,
			PrimaryParentUID,
			ConfigState,
			LastConfigStart,
			LastConfigJobId,
			ConfigFailReason,
			PolicyQuarantined
		FROM #DistributionServer
	SET @count = @@ROWCOUNT
	DROP TABLE #DistributionServer	-- Drop temporary table
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[DistributionServerUpdateByServerUID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[DistributionServerUpdateByServerUID]
GO
CREATE PROCEDURE [dbo].[DistributionServerUpdateByServerUID]
	@ServerUID		binary(16),
	@DNSName		nvarchar(128) = NULL,
	@ServerType		smallint = 0,
	@ServerName		nvarchar(64),
	@PrimaryParentUID	binary(16) = NULL,
	@ConfigState		nvarchar(20) = NULL,
	@LastConfigStart	datetime = NULL,
	@LastConfigJobId	nvarchar(40) = NULL,
	@ConfigFailReason	ntext = NULL,
	@PolicyQuarantined	bit = 0
AS
	UPDATE	[dbo].[DistributionServer]
	SET	DNSName = @DNSName,
		ServerType = @ServerType,
		ServerName = @ServerName,
		PrimaryParentUID = @PrimaryParentUID,
		ConfigState = @ConfigState,
		LastConfigStart = @LastConfigStart,
		LastConfigJobId = @LastConfigJobId,
		ConfigFailReason = @ConfigFailReason,
		PolicyQuarantined = @PolicyQuarantined
	WHERE	ServerUID = @ServerUID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[DistributionServerUpdateBatchByServerUID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[DistributionServerUpdateBatchByServerUID]
GO
CREATE PROCEDURE dbo.[DistributionServerUpdateBatchByServerUID]
AS
	DECLARE @count int

	CREATE INDEX [TempDistributionServerServerUID]
		ON #DistributionServer (ServerUID)

	UPDATE	[dbo].[DistributionServer]
	SET	DNSName = t.DNSName,
		ServerType = t.ServerType,
		ServerName = t.ServerName,
		PrimaryParentUID = t.PrimaryParentUID,
		ConfigState = t.ConfigState,
		LastConfigStart = t.LastConfigStart,
		LastConfigJobId = t.LastConfigJobId,
		ConfigFailReason = t.ConfigFailReason,
		PolicyQuarantined = t.PolicyQuarantined
	FROM	#DistributionServer AS t
	WHERE	DistributionServer.ServerUID = t.ServerUID
	SET @count = @@ROWCOUNT
	DROP TABLE #DistributionServer	-- Drop the temporary table
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[DistributionServerPutByServerUID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[DistributionServerPutByServerUID]
GO
CREATE PROCEDURE [dbo].[DistributionServerPutByServerUID]
	@ServerUID		binary(16),
	@DNSName		nvarchar(128) = NULL,
	@ServerType		smallint = 0,
	@ServerName		nvarchar(64),
	@PrimaryParentUID	binary(16) = NULL,
	@ConfigState		nvarchar(20) = NULL,
	@LastConfigStart	datetime = NULL,
	@LastConfigJobId	nvarchar(40) = NULL,
	@ConfigFailReason	ntext = NULL,
	@PolicyQuarantined	bit = 0
AS
	IF NOT EXISTS(
		SELECT	1
		FROM	dbo.DistributionServer
		WHERE	ServerUID = @ServerUID
	)
		EXEC DistributionServerAdd @ServerUID,
			@DNSName,
			@ServerType,
			@ServerName,
			@PrimaryParentUID,
			@ConfigState,
			@LastConfigStart,
			@LastConfigJobId,
			@ConfigFailReason,
			@PolicyQuarantined
	ELSE
		EXEC DistributionServerUpdateByServerUID @ServerUID,
			@DNSName,
			@ServerType,
			@ServerName,
			@PrimaryParentUID,
			@ConfigState,
			@LastConfigStart,
			@LastConfigJobId,
			@ConfigFailReason,
			@PolicyQuarantined
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[DistributionServerPutBatchByServerUID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[DistributionServerPutBatchByServerUID]
GO
CREATE PROCEDURE [dbo].[DistributionServerPutBatchByServerUID]
AS
	DECLARE @count AS int
	SET @count = 0

	CREATE INDEX [TempDistributionServerServerUID]
		ON #DistributionServer (ServerUID)

	BEGIN TRANSACTION
	UPDATE [dbo].[DistributionServer]
		SET	DNSName = t.DNSName,
			ServerType = t.ServerType,
			ServerName = t.ServerName,
			PrimaryParentUID = t.PrimaryParentUID,
			ConfigState = t.ConfigState,
			LastConfigStart = t.LastConfigStart,
			LastConfigJobId = t.LastConfigJobId,
			ConfigFailReason = t.ConfigFailReason,
			PolicyQuarantined = t.PolicyQuarantined
		FROM	#DistributionServer AS t
		WHERE	DistributionServer.ServerUID = t.ServerUID
	SET @count = @@ROWCOUNT

	INSERT [dbo].[DistributionServer] (
		ServerUID,
		DNSName,
		ServerType,
		ServerName,
		PrimaryParentUID,
		ConfigState,
		LastConfigStart,
		LastConfigJobId,
		ConfigFailReason,
		PolicyQuarantined
	)
		SELECT	ServerUID,
			DNSName,
			ServerType,
			ServerName,
			PrimaryParentUID,
			ConfigState,
			LastConfigStart,
			LastConfigJobId,
			ConfigFailReason,
			PolicyQuarantined
		FROM	#DistributionServer AS t
		WHERE NOT EXISTS(	-- Current record doesn't exist
			SELECT * FROM [dbo].[DistributionServer]
			WHERE	DistributionServer.ServerUID = t.ServerUID
		)
	SET @count = @count + @@ROWCOUNT
	DROP TABLE #DistributionServer	-- Drop the temporary table
	COMMIT WORK
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[DistributionServerRemoveBatch]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[DistributionServerRemoveBatch]
GO

CREATE PROCEDURE [dbo].[DistributionServerRemoveBatch]
AS

	CREATE INDEX [TempDistributionServerDistributionServerRemoveBatch]
		ON #DistributionServer (ServerUID)	

	-- Delete records from DistributionServer identified by fields of [TempDistributionServerDistributionServerRemoveBatch]
	DELETE [dbo].[DistributionServer]
	WHERE EXISTS(
			SELECT * FROM #DistributionServer AS t
			WHERE	DistributionServer.ServerUID = t.ServerUID
		)
	DROP TABLE #DistributionServer      -- Drop the temporary table
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[DistributionServerRemoveByServerUID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[DistributionServerRemoveByServerUID]
GO
CREATE PROCEDURE [dbo].[DistributionServerRemoveByServerUID]
	@ServerUID		binary(16)
AS
	-- DistributionServer deletes cascade to:
	--	DistributionServerStatus by FK_DistributionServerStatus_ServerUID
	--	DistributedPackage by FK_DistributedPackage_ServerUID
	--	DistributionServerAdministrationAccount by FK_DSAdministrationAccount_Server
	--	NetworkDeviceDiscoveredBy by FK_NetworkDeviceDiscoveredBy_Server
	--	Job by FK_Job_Server
	--		Action by FK_Action_Job
	--			ActionApplies by FK_ActionApplies_Action
	--	WakeOnLANDistributionJob by FK_WOLDistJob_Server
	--		WakeOnLANStatus by FK_WOLStatus_DistJob
	-- DistributionServer deletes may fail due to non-cascading FKs:
	--	DistributionServer by FK_DistributionServer_PrimaryParent
	--	Action by FK_Action_Server
	DELETE	[dbo].[DistributionServer]
	WHERE	ServerUID = @ServerUID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[DistributionServerRemoveAll]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[DistributionServerRemoveAll]
GO
CREATE PROCEDURE [dbo].[DistributionServerRemoveAll]
	
AS
	DELETE	[dbo].[DistributionServer]
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[DistributionServerStatusGetByServerUIDTypeName]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[DistributionServerStatusGetByServerUIDTypeName]
GO
CREATE PROCEDURE [dbo].[DistributionServerStatusGetByServerUIDTypeName]
	@ServerUID		binary(16),
	@Type			varchar(32),
	@Name			varchar(64)
AS
	SELECT	ServerUID,
		ReportedDate,
		Type,
		[Name],
		Count,
		DelayedCount
	FROM	[dbo].[DistributionServerStatus]
	WHERE	ServerUID = @ServerUID
	  AND	Type = @Type
	  AND	[Name] = @Name
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[DistributionServerStatusGetAllByServerUID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[DistributionServerStatusGetAllByServerUID]
GO
CREATE PROCEDURE [dbo].[DistributionServerStatusGetAllByServerUID]
	@ServerUID		binary(16)
AS
	SELECT	ServerUID,
		ReportedDate,
		Type,
		[Name],
		Count,
		DelayedCount
	FROM	[dbo].[DistributionServerStatus]
	WHERE	ServerUID = @ServerUID
	ORDER BY Type, [Name]
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[DistributionServerStatusGetAll]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[DistributionServerStatusGetAll]
GO
CREATE PROCEDURE [dbo].[DistributionServerStatusGetAll]
AS
	SELECT	ServerUID,
		ReportedDate,
		Type,
		[Name],
		Count,
		DelayedCount
	FROM	[dbo].[DistributionServerStatus]
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[DistributionServerStatusAdd]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[DistributionServerStatusAdd]
GO
CREATE PROCEDURE [dbo].[DistributionServerStatusAdd]
	@ServerUID		binary(16),
	@ReportedDate		datetime,
	@Type			varchar(32),
	@Name			varchar(64),
	@Count			int,
	@DelayedCount		int
AS
	INSERT INTO  dbo.DistributionServerStatus (
		ServerUID,
		ReportedDate,
		Type,
		[Name],
		Count,
		DelayedCount
	)
	VALUES (
		@ServerUID,
		@ReportedDate,
		@Type,
		@Name,
		@Count,
		@DelayedCount
	)
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[DistributionServerStatusSchema]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[DistributionServerStatusSchema]
GO
CREATE PROCEDURE [dbo].[DistributionServerStatusSchema]
AS
	SELECT
	'IF OBJECT_ID(''tempdb..#DistributionServerStatus'') IS NULL' + CAST(0x0A AS CHAR(1)) +
	'	CREATE TABLE #DistributionServerStatus (' + CAST(0x0A AS CHAR(1)) +
	'		ServerUID		binary(16) NOT NULL,' + CAST(0x0A AS CHAR(1)) +
	'		ReportedDate		datetime NOT NULL,' + CAST(0x0A AS CHAR(1)) +
	'		Type			varchar(32) COLLATE database_default NOT NULL,' + CAST(0x0A AS CHAR(1)) +
	'		[Name]			varchar(64) COLLATE database_default NOT NULL,' + CAST(0x0A AS CHAR(1)) +
	'		Count			int NOT NULL,' + CAST(0x0A AS CHAR(1)) +
	'		DelayedCount		int NOT NULL' + CAST(0x0A AS CHAR(1)) +
	'	)' + CAST(0x0A AS CHAR(1)) +
	'ELSE' + CAST(0x0A AS CHAR(1)) +
	'	DELETE FROM #DistributionServerStatus' + CAST(0x0A AS CHAR(1)) +
	'' AS SQL
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[DistributionServerStatusTempAdd]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[DistributionServerStatusTempAdd]
GO
CREATE PROCEDURE dbo.[DistributionServerStatusTempAdd]
	@ServerUID		binary(16),
	@ReportedDate		datetime,
	@Type			varchar(32),
	@Name			varchar(64),
	@Count			int,
	@DelayedCount		int
AS
	INSERT INTO #DistributionServerStatus (
		ServerUID,
		ReportedDate,
		Type,
		[Name],
		Count,
		DelayedCount
	)
	VALUES (
		@ServerUID,
		@ReportedDate,
		@Type,
		@Name,
		@Count,
		@DelayedCount
	)
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[DistributionServerStatusAddBatch]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[DistributionServerStatusAddBatch]
GO
CREATE PROCEDURE dbo.[DistributionServerStatusAddBatch]
AS
	DECLARE @count int
	INSERT dbo.DistributionServerStatus (
		ServerUID,
		ReportedDate,
		Type,
		[Name],
		Count,
		DelayedCount
	)
		SELECT	ServerUID,
			ReportedDate,
			Type,
			[Name],
			Count,
			DelayedCount
		FROM #DistributionServerStatus
	SET @count = @@ROWCOUNT
	DROP TABLE #DistributionServerStatus	-- Drop temporary table
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[DistributionServerStatusUpdateByServerUIDTypeName]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[DistributionServerStatusUpdateByServerUIDTypeName]
GO
CREATE PROCEDURE [dbo].[DistributionServerStatusUpdateByServerUIDTypeName]
	@ServerUID		binary(16),
	@Type			varchar(32),
	@Name			varchar(64),
	@ReportedDate		datetime,
	@Count			int,
	@DelayedCount		int
AS
	UPDATE	[dbo].[DistributionServerStatus]
	SET	ReportedDate = @ReportedDate,
		Count = @Count,
		DelayedCount = @DelayedCount
	WHERE	ServerUID = @ServerUID
	  AND	Type = @Type
	  AND	[Name] = @Name
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[DistributionServerStatusUpdateBatchByServerUIDTypeName]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[DistributionServerStatusUpdateBatchByServerUIDTypeName]
GO
CREATE PROCEDURE dbo.[DistributionServerStatusUpdateBatchByServerUIDTypeName]
AS
	DECLARE @count int

	CREATE INDEX [TempDistributionServerStatusServerUIDTypeName]
		ON #DistributionServerStatus (ServerUID, Type, [Name])

	UPDATE	[dbo].[DistributionServerStatus]
	SET	ReportedDate = t.ReportedDate,
		Count = t.Count,
		DelayedCount = t.DelayedCount
	FROM	#DistributionServerStatus AS t
	WHERE	DistributionServerStatus.ServerUID = t.ServerUID
	  AND	DistributionServerStatus.Type = t.Type
	  AND	DistributionServerStatus.[Name] = t.[Name]
	SET @count = @@ROWCOUNT
	DROP TABLE #DistributionServerStatus	-- Drop the temporary table
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[DistributionServerStatusPutByServerUIDTypeName]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[DistributionServerStatusPutByServerUIDTypeName]
GO
CREATE PROCEDURE [dbo].[DistributionServerStatusPutByServerUIDTypeName]
	@ServerUID		binary(16),
	@Type			varchar(32),
	@Name			varchar(64),
	@ReportedDate		datetime,
	@Count			int,
	@DelayedCount		int
AS
	IF NOT EXISTS(
		SELECT	1
		FROM	dbo.DistributionServerStatus
		WHERE	ServerUID = @ServerUID
		  AND	Type = @Type
		  AND	[Name] = @Name
	)
		EXEC DistributionServerStatusAdd @ServerUID,
			@ReportedDate,
			@Type,
			@Name,
			@Count,
			@DelayedCount
	ELSE
		EXEC DistributionServerStatusUpdateByServerUIDTypeName @ServerUID,
			@Type,
			@Name,
			@ReportedDate,
			@Count,
			@DelayedCount
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[DistributionServerStatusPutBatchByServerUIDTypeName]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[DistributionServerStatusPutBatchByServerUIDTypeName]
GO
CREATE PROCEDURE [dbo].[DistributionServerStatusPutBatchByServerUIDTypeName]
AS
	DECLARE @count AS int
	SET @count = 0

	CREATE INDEX [TempDistributionServerStatusServerUIDTypeName]
		ON #DistributionServerStatus (ServerUID, Type, [Name])

	BEGIN TRANSACTION
	UPDATE [dbo].[DistributionServerStatus]
		SET	ReportedDate = t.ReportedDate,
			Count = t.Count,
			DelayedCount = t.DelayedCount
		FROM	#DistributionServerStatus AS t
		WHERE	DistributionServerStatus.ServerUID = t.ServerUID
		  AND	DistributionServerStatus.Type = t.Type
		  AND	DistributionServerStatus.[Name] = t.[Name]
	SET @count = @@ROWCOUNT

	INSERT [dbo].[DistributionServerStatus] (
		ServerUID,
		ReportedDate,
		Type,
		[Name],
		Count,
		DelayedCount
	)
		SELECT	ServerUID,
			ReportedDate,
			Type,
			[Name],
			Count,
			DelayedCount
		FROM	#DistributionServerStatus AS t
		WHERE NOT EXISTS(	-- Current record doesn't exist
			SELECT * FROM [dbo].[DistributionServerStatus]
			WHERE	DistributionServerStatus.ServerUID = t.ServerUID
			  AND	DistributionServerStatus.Type = t.Type
			  AND	DistributionServerStatus.[Name] = t.[Name]
		)
	SET @count = @count + @@ROWCOUNT
	DROP TABLE #DistributionServerStatus	-- Drop the temporary table
	COMMIT WORK
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[DistributionServerStatusRemoveBatch]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[DistributionServerStatusRemoveBatch]
GO

CREATE PROCEDURE [dbo].[DistributionServerStatusRemoveBatch]
AS

	CREATE INDEX [TempDistributionServerStatusDistributionServerStatusRemoveBatch]
		ON #DistributionServerStatus (ServerUID, Type, [Name])	

	-- Delete records from DistributionServerStatus identified by fields of [TempDistributionServerStatusDistributionServerStatusRemoveBatch]
	DELETE [dbo].[DistributionServerStatus]
	WHERE EXISTS(
			SELECT * FROM #DistributionServerStatus AS t
			WHERE	DistributionServerStatus.ServerUID = t.ServerUID
			  AND	DistributionServerStatus.Type = t.Type
			  AND	DistributionServerStatus.[Name] = t.[Name]
		)
	DROP TABLE #DistributionServerStatus      -- Drop the temporary table
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[DistributionServerStatusRemoveByServerUIDTypeName]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[DistributionServerStatusRemoveByServerUIDTypeName]
GO
CREATE PROCEDURE [dbo].[DistributionServerStatusRemoveByServerUIDTypeName]
	@ServerUID		binary(16),
	@Type			varchar(32),
	@Name			varchar(64)
AS
	DELETE	[dbo].[DistributionServerStatus]
	WHERE	ServerUID = @ServerUID
	  AND	Type = @Type
	  AND	[Name] = @Name
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[DistributionServerStatusRemoveAllByServerUID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[DistributionServerStatusRemoveAllByServerUID]
GO
CREATE PROCEDURE [dbo].[DistributionServerStatusRemoveAllByServerUID]
	@ServerUID		binary(16)
AS
	DELETE	[dbo].[DistributionServerStatus]
	WHERE	ServerUID = @ServerUID
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[DistributionServerStatusRemoveAll]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[DistributionServerStatusRemoveAll]
GO
CREATE PROCEDURE [dbo].[DistributionServerStatusRemoveAll]
	
AS
	DELETE	[dbo].[DistributionServerStatus]
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[DistributionServerStatusReplaceSubsetByServerUID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[DistributionServerStatusReplaceSubsetByServerUID]
GO
-- Replace the record subset selected by (@ServerUID)
-- using unique identifier (ServerUID, Type, [Name])
-- updating fields (ReportedDate, Count, DelayedCount)
CREATE PROCEDURE [dbo].[DistributionServerStatusReplaceSubsetByServerUID]
	@ServerUID		binary(16)
AS
	DECLARE @count AS int
	SET @count = 0

	CREATE INDEX [TempDistributionServerStatusByServerUID]
		ON #DistributionServerStatus (ServerUID, Type, [Name])

	BEGIN TRANSACTION
	DELETE [DistributionServerStatus]
		WHERE	ServerUID = @ServerUID
		AND NOT EXISTS(		-- Replacement record doesn't exist
			SELECT * FROM #DistributionServerStatus AS t
			WHERE	DistributionServerStatus.ServerUID = t.ServerUID
			  AND	DistributionServerStatus.Type = t.Type
			  AND	DistributionServerStatus.[Name] = t.[Name]
		)

	UPDATE [dbo].[DistributionServerStatus]
		SET	ReportedDate = t.ReportedDate,
			Count = t.Count,
			DelayedCount = t.DelayedCount
		FROM	#DistributionServerStatus AS t
		WHERE	DistributionServerStatus.ServerUID = t.ServerUID
		  AND	DistributionServerStatus.Type = t.Type
		  AND	DistributionServerStatus.[Name] = t.[Name]
	SET @count = @@ROWCOUNT

	INSERT [DistributionServerStatus] (
		ServerUID,
		ReportedDate,
		Type,
		[Name],
		Count,
		DelayedCount
	)
		SELECT	ServerUID,
			ReportedDate,
			Type,
			[Name],
			Count,
			DelayedCount
		FROM	#DistributionServerStatus AS t
		WHERE NOT EXISTS(	-- Current record doesn't exist
			SELECT * FROM [DistributionServerStatus]
			WHERE	DistributionServerStatus.ServerUID = t.ServerUID
			  AND	DistributionServerStatus.Type = t.Type
			  AND	DistributionServerStatus.[Name] = t.[Name]
		)
	SET @count = @count + @@ROWCOUNT
	DROP TABLE #DistributionServerStatus	-- Drop the temporary table
	COMMIT WORK
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[DistributedPackageGetByID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[DistributedPackageGetByID]
GO
CREATE PROCEDURE [dbo].[DistributedPackageGetByID]
	@DistributedPackageID	int
AS
	SELECT	DistributedPackageID,
		ServerUID,
		RequestedVersionID,
		RequestState,
		RequestDate,
		ConfirmedVersionID,
		ConfirmedState,
		ConfirmedDate,
		ConfirmedReason
	FROM	[dbo].[DistributedPackage]
	WHERE	DistributedPackageID = @DistributedPackageID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[DistributedPackageGetByServerUIDRequestedVersionID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[DistributedPackageGetByServerUIDRequestedVersionID]
GO
CREATE PROCEDURE [dbo].[DistributedPackageGetByServerUIDRequestedVersionID]
	@ServerUID		binary(16),
	@RequestedVersionID	int = NULL
AS
	SELECT	DistributedPackageID,
		ServerUID,
		RequestedVersionID,
		RequestState,
		RequestDate,
		ConfirmedVersionID,
		ConfirmedState,
		ConfirmedDate,
		ConfirmedReason
	FROM	[dbo].[DistributedPackage]
	WHERE	ServerUID = @ServerUID
	  AND	(RequestedVersionID = @RequestedVersionID OR (RequestedVersionID IS NULL AND @RequestedVersionID IS NULL))
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[DistributedPackageGetAllByConfirmedVersionID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[DistributedPackageGetAllByConfirmedVersionID]
GO
CREATE PROCEDURE [dbo].[DistributedPackageGetAllByConfirmedVersionID]
	@ConfirmedVersionID	int = NULL
AS
	SELECT	DistributedPackageID,
		ServerUID,
		RequestedVersionID,
		RequestState,
		RequestDate,
		ConfirmedVersionID,
		ConfirmedState,
		ConfirmedDate,
		ConfirmedReason
	FROM	[dbo].[DistributedPackage]
	WHERE	(ConfirmedVersionID = @ConfirmedVersionID OR (ConfirmedVersionID IS NULL AND @ConfirmedVersionID IS NULL))
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[DistributedPackageGetAllByRequestedVersionID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[DistributedPackageGetAllByRequestedVersionID]
GO
CREATE PROCEDURE [dbo].[DistributedPackageGetAllByRequestedVersionID]
	@RequestedVersionID	int = NULL
AS
	SELECT	DistributedPackageID,
		ServerUID,
		RequestedVersionID,
		RequestState,
		RequestDate,
		ConfirmedVersionID,
		ConfirmedState,
		ConfirmedDate,
		ConfirmedReason
	FROM	[dbo].[DistributedPackage]
	WHERE	(RequestedVersionID = @RequestedVersionID OR (RequestedVersionID IS NULL AND @RequestedVersionID IS NULL))
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[DistributedPackageGetAll]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[DistributedPackageGetAll]
GO
CREATE PROCEDURE [dbo].[DistributedPackageGetAll]
AS
	SELECT	DistributedPackageID,
		ServerUID,
		RequestedVersionID,
		RequestState,
		RequestDate,
		ConfirmedVersionID,
		ConfirmedState,
		ConfirmedDate,
		ConfirmedReason
	FROM	[dbo].[DistributedPackage]
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[DistributedPackageAdd]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[DistributedPackageAdd]
GO
CREATE PROCEDURE [dbo].[DistributedPackageAdd]
	@ServerUID		binary(16),
	@RequestedVersionID	int = NULL,
	@RequestState		nvarchar(16) = NULL,
	@RequestDate		datetime = NULL,
	@ConfirmedVersionID	int = NULL,
	@ConfirmedState		nvarchar(16) = NULL,
	@ConfirmedDate		datetime = NULL,
	@ConfirmedReason	ntext = NULL
AS
	INSERT INTO  dbo.DistributedPackage (
		ServerUID,
		RequestedVersionID,
		RequestState,
		RequestDate,
		ConfirmedVersionID,
		ConfirmedState,
		ConfirmedDate,
		ConfirmedReason
	)
	VALUES (
		@ServerUID,
		@RequestedVersionID,
		@RequestState,
		@RequestDate,
		@ConfirmedVersionID,
		@ConfirmedState,
		@ConfirmedDate,
		@ConfirmedReason
	)
	RETURN SCOPE_IDENTITY()
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[DistributedPackageBind]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[DistributedPackageBind]
GO
CREATE PROCEDURE [dbo].[DistributedPackageBind]
	@ServerUID		binary(16),
	@RequestedVersionID	int = NULL,
	@RequestState		nvarchar(16) = NULL,
	@RequestDate		datetime = NULL,
	@ConfirmedVersionID	int = NULL,
	@ConfirmedState		nvarchar(16) = NULL,
	@ConfirmedDate		datetime = NULL,
	@ConfirmedReason	ntext = NULL
AS
	DECLARE	@ID	int

	SELECT	@ID = DistributedPackageID
	FROM	[dbo].[DistributedPackage]
	WHERE	ServerUID = @ServerUID
	  AND	(RequestedVersionID = @RequestedVersionID OR (RequestedVersionID IS NULL AND @RequestedVersionID IS NULL))

	IF @ID IS NULL
		EXEC @ID = DistributedPackageAdd @ServerUID,
			@RequestedVersionID,
			@RequestState,
			@RequestDate,
			@ConfirmedVersionID,
			@ConfirmedState,
			@ConfirmedDate,
			@ConfirmedReason

	RETURN @ID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[DistributedPackageSchema]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[DistributedPackageSchema]
GO
CREATE PROCEDURE [dbo].[DistributedPackageSchema]
AS
	SELECT
	'IF OBJECT_ID(''tempdb..#DistributedPackage'') IS NULL' + CAST(0x0A AS CHAR(1)) +
	'	CREATE TABLE #DistributedPackage (' + CAST(0x0A AS CHAR(1)) +
	'		DistributedPackageID	int NULL,' + CAST(0x0A AS CHAR(1)) +
	'		ServerUID		binary(16) NOT NULL,' + CAST(0x0A AS CHAR(1)) +
	'		RequestedVersionID	int NULL,' + CAST(0x0A AS CHAR(1)) +
	'		RequestState		nvarchar(16) COLLATE database_default NULL,' + CAST(0x0A AS CHAR(1)) +
	'		RequestDate		datetime NULL,' + CAST(0x0A AS CHAR(1)) +
	'		ConfirmedVersionID	int NULL,' + CAST(0x0A AS CHAR(1)) +
	'		ConfirmedState		nvarchar(16) COLLATE database_default NULL,' + CAST(0x0A AS CHAR(1)) +
	'		ConfirmedDate		datetime NULL,' + CAST(0x0A AS CHAR(1)) +
	'		ConfirmedReason		ntext COLLATE database_default NULL' + CAST(0x0A AS CHAR(1)) +
	'	)' + CAST(0x0A AS CHAR(1)) +
	'ELSE' + CAST(0x0A AS CHAR(1)) +
	'	DELETE FROM #DistributedPackage' + CAST(0x0A AS CHAR(1)) +
	'' AS SQL
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[DistributedPackageTempAdd]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[DistributedPackageTempAdd]
GO
CREATE PROCEDURE dbo.[DistributedPackageTempAdd]
	@DistributedPackageID	int,
	@ServerUID		binary(16),
	@RequestedVersionID	int = NULL,
	@RequestState		nvarchar(16) = NULL,
	@RequestDate		datetime = NULL,
	@ConfirmedVersionID	int = NULL,
	@ConfirmedState		nvarchar(16) = NULL,
	@ConfirmedDate		datetime = NULL,
	@ConfirmedReason	ntext = NULL
AS
	INSERT INTO #DistributedPackage (
		DistributedPackageID,
		ServerUID,
		RequestedVersionID,
		RequestState,
		RequestDate,
		ConfirmedVersionID,
		ConfirmedState,
		ConfirmedDate,
		ConfirmedReason
	)
	VALUES (
		@DistributedPackageID,
		@ServerUID,
		@RequestedVersionID,
		@RequestState,
		@RequestDate,
		@ConfirmedVersionID,
		@ConfirmedState,
		@ConfirmedDate,
		@ConfirmedReason
	)
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[DistributedPackageAddBatch]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[DistributedPackageAddBatch]
GO
CREATE PROCEDURE dbo.[DistributedPackageAddBatch]
AS
	DECLARE @count int
	INSERT dbo.DistributedPackage (
		ServerUID,
		RequestedVersionID,
		RequestState,
		RequestDate,
		ConfirmedVersionID,
		ConfirmedState,
		ConfirmedDate,
		ConfirmedReason
	)
		SELECT	ServerUID,
			RequestedVersionID,
			RequestState,
			RequestDate,
			ConfirmedVersionID,
			ConfirmedState,
			ConfirmedDate,
			ConfirmedReason
		FROM #DistributedPackage
	SET @count = @@ROWCOUNT
	DROP TABLE #DistributedPackage	-- Drop temporary table
	RETURN @count
GO

/*
Add new DistributedPackage bound to
	PackageVersion using PackagePathID, Version, Update with PackageFamilyID
	PackageVersion using PackagePathID, Version, Update with PackageFamilyID
	with ServerUID, RequestState, RequestDate, ConfirmedState, ConfirmedDate, ConfirmedReason
*/

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[DistributedPackageUpdateByID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[DistributedPackageUpdateByID]
GO
CREATE PROCEDURE [dbo].[DistributedPackageUpdateByID]
	@DistributedPackageID	int,
	@ServerUID		binary(16),
	@RequestedVersionID	int = NULL,
	@RequestState		nvarchar(16) = NULL,
	@RequestDate		datetime = NULL,
	@ConfirmedVersionID	int = NULL,
	@ConfirmedState		nvarchar(16) = NULL,
	@ConfirmedDate		datetime = NULL,
	@ConfirmedReason	ntext = NULL
AS
	DECLARE	@ID	int
	SET @ID = 0

	UPDATE	[dbo].[DistributedPackage]
	SET	@ID = DistributedPackageID,
		ServerUID = @ServerUID,
		RequestedVersionID = @RequestedVersionID,
		RequestState = @RequestState,
		RequestDate = @RequestDate,
		ConfirmedVersionID = @ConfirmedVersionID,
		ConfirmedState = @ConfirmedState,
		ConfirmedDate = @ConfirmedDate,
		ConfirmedReason = @ConfirmedReason
	WHERE	DistributedPackageID = @DistributedPackageID
	RETURN @ID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[DistributedPackageUpdateBatchByID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[DistributedPackageUpdateBatchByID]
GO
CREATE PROCEDURE dbo.[DistributedPackageUpdateBatchByID]
AS
	DECLARE @count int

	CREATE INDEX [TempDistributedPackageID]
		ON #DistributedPackage (DistributedPackageID)

	UPDATE	[dbo].[DistributedPackage]
	SET	ServerUID = t.ServerUID,
		RequestedVersionID = t.RequestedVersionID,
		RequestState = t.RequestState,
		RequestDate = t.RequestDate,
		ConfirmedVersionID = t.ConfirmedVersionID,
		ConfirmedState = t.ConfirmedState,
		ConfirmedDate = t.ConfirmedDate,
		ConfirmedReason = t.ConfirmedReason
	FROM	#DistributedPackage AS t
	WHERE	DistributedPackage.DistributedPackageID = t.DistributedPackageID
	SET @count = @@ROWCOUNT
	DROP TABLE #DistributedPackage	-- Drop the temporary table
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[DistributedPackageUpdateByServerUIDRequestedVersionID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[DistributedPackageUpdateByServerUIDRequestedVersionID]
GO
CREATE PROCEDURE [dbo].[DistributedPackageUpdateByServerUIDRequestedVersionID]
	@ServerUID		binary(16),
	@RequestedVersionID	int = NULL,
	@RequestState		nvarchar(16) = NULL,
	@RequestDate		datetime = NULL,
	@ConfirmedVersionID	int = NULL,
	@ConfirmedState		nvarchar(16) = NULL,
	@ConfirmedDate		datetime = NULL,
	@ConfirmedReason	ntext = NULL
AS
	DECLARE	@ID	int
	SET @ID = 0

	UPDATE	[dbo].[DistributedPackage]
	SET	@ID = DistributedPackageID,
		RequestState = @RequestState,
		RequestDate = @RequestDate,
		ConfirmedVersionID = @ConfirmedVersionID,
		ConfirmedState = @ConfirmedState,
		ConfirmedDate = @ConfirmedDate,
		ConfirmedReason = @ConfirmedReason
	WHERE	ServerUID = @ServerUID
	  AND	(RequestedVersionID = @RequestedVersionID OR (RequestedVersionID IS NULL AND @RequestedVersionID IS NULL))
	RETURN @ID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[DistributedPackageUpdateBatchByServerUIDRequestedVersionID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[DistributedPackageUpdateBatchByServerUIDRequestedVersionID]
GO
CREATE PROCEDURE dbo.[DistributedPackageUpdateBatchByServerUIDRequestedVersionID]
AS
	DECLARE @count int

	CREATE INDEX [TempDistributedPackageServerUIDRequestedVersionID]
		ON #DistributedPackage (ServerUID, RequestedVersionID)

	UPDATE	[dbo].[DistributedPackage]
	SET	RequestState = t.RequestState,
		RequestDate = t.RequestDate,
		ConfirmedVersionID = t.ConfirmedVersionID,
		ConfirmedState = t.ConfirmedState,
		ConfirmedDate = t.ConfirmedDate,
		ConfirmedReason = t.ConfirmedReason
	FROM	#DistributedPackage AS t
	WHERE	DistributedPackage.ServerUID = t.ServerUID
	  AND	(DistributedPackage.RequestedVersionID = t.RequestedVersionID OR (DistributedPackage.RequestedVersionID IS NULL AND t.RequestedVersionID IS NULL))
	SET @count = @@ROWCOUNT
	DROP TABLE #DistributedPackage	-- Drop the temporary table
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[DistributedPackagePutByServerUIDRequestedVersionID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[DistributedPackagePutByServerUIDRequestedVersionID]
GO
CREATE PROCEDURE [dbo].[DistributedPackagePutByServerUIDRequestedVersionID]
	@ServerUID		binary(16),
	@RequestedVersionID	int = NULL,
	@RequestState		nvarchar(16) = NULL,
	@RequestDate		datetime = NULL,
	@ConfirmedVersionID	int = NULL,
	@ConfirmedState		nvarchar(16) = NULL,
	@ConfirmedDate		datetime = NULL,
	@ConfirmedReason	ntext = NULL
AS
	DECLARE @ID	int

	SELECT	@ID = DistributedPackageID
	FROM	DistributedPackage
	WHERE	ServerUID = @ServerUID
	  AND	(RequestedVersionID = @RequestedVersionID OR (RequestedVersionID IS NULL AND @RequestedVersionID IS NULL))

	IF @ID IS NULL
		EXEC @ID = DistributedPackageAdd @ServerUID,
			@RequestedVersionID,
			@RequestState,
			@RequestDate,
			@ConfirmedVersionID,
			@ConfirmedState,
			@ConfirmedDate,
			@ConfirmedReason
	ELSE
		EXEC DistributedPackageUpdateByServerUIDRequestedVersionID @ServerUID,
			@RequestedVersionID,
			@RequestState,
			@RequestDate,
			@ConfirmedVersionID,
			@ConfirmedState,
			@ConfirmedDate,
			@ConfirmedReason

	RETURN @ID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[DistributedPackagePutBatchByServerUIDRequestedVersionID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[DistributedPackagePutBatchByServerUIDRequestedVersionID]
GO
CREATE PROCEDURE [dbo].[DistributedPackagePutBatchByServerUIDRequestedVersionID]
AS
	DECLARE @count AS int
	SET @count = 0

	CREATE INDEX [TempDistributedPackageServerUIDRequestedVersionID]
		ON #DistributedPackage (ServerUID, RequestedVersionID)

	BEGIN TRANSACTION
	UPDATE [dbo].[DistributedPackage]
		SET	RequestState = t.RequestState,
			RequestDate = t.RequestDate,
			ConfirmedVersionID = t.ConfirmedVersionID,
			ConfirmedState = t.ConfirmedState,
			ConfirmedDate = t.ConfirmedDate,
			ConfirmedReason = t.ConfirmedReason
		FROM	#DistributedPackage AS t
		WHERE	DistributedPackage.ServerUID = t.ServerUID
		  AND	(DistributedPackage.RequestedVersionID = t.RequestedVersionID OR (DistributedPackage.RequestedVersionID IS NULL AND t.RequestedVersionID IS NULL))
	SET @count = @@ROWCOUNT

	INSERT [dbo].[DistributedPackage] (
		ServerUID,
		RequestedVersionID,
		RequestState,
		RequestDate,
		ConfirmedVersionID,
		ConfirmedState,
		ConfirmedDate,
		ConfirmedReason
	)
		SELECT	ServerUID,
			RequestedVersionID,
			RequestState,
			RequestDate,
			ConfirmedVersionID,
			ConfirmedState,
			ConfirmedDate,
			ConfirmedReason
		FROM	#DistributedPackage AS t
		WHERE NOT EXISTS(	-- Current record doesn't exist
			SELECT * FROM [dbo].[DistributedPackage]
			WHERE	DistributedPackage.ServerUID = t.ServerUID
			  AND	(DistributedPackage.RequestedVersionID = t.RequestedVersionID OR (DistributedPackage.RequestedVersionID IS NULL AND t.RequestedVersionID IS NULL))
		)
	SET @count = @count + @@ROWCOUNT
	DROP TABLE #DistributedPackage	-- Drop the temporary table
	COMMIT WORK
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[DistributedPackageRemoveBatch]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[DistributedPackageRemoveBatch]
GO

CREATE PROCEDURE [dbo].[DistributedPackageRemoveBatch]
AS

	CREATE INDEX [TempDistributedPackageDistributedPackageRemoveBatch]
		ON #DistributedPackage (DistributedPackageID)	

	-- Delete records from DistributedPackage identified by fields of [TempDistributedPackageDistributedPackageRemoveBatch]
	DELETE [dbo].[DistributedPackage]
	WHERE EXISTS(
			SELECT * FROM #DistributedPackage AS t
			WHERE	DistributedPackage.DistributedPackageID = t.DistributedPackageID
		)
	DROP TABLE #DistributedPackage      -- Drop the temporary table
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[DistributedPackageRemoveByID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[DistributedPackageRemoveByID]
GO
CREATE PROCEDURE [dbo].[DistributedPackageRemoveByID]
	@DistributedPackageID	int
AS
	DELETE	[dbo].[DistributedPackage]
	WHERE	DistributedPackageID = @DistributedPackageID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[DistributedPackageRemoveAllByConfirmedVersionID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[DistributedPackageRemoveAllByConfirmedVersionID]
GO
CREATE PROCEDURE [dbo].[DistributedPackageRemoveAllByConfirmedVersionID]
	@ConfirmedVersionID	int = NULL
AS
	DELETE	[dbo].[DistributedPackage]
	WHERE	(ConfirmedVersionID = @ConfirmedVersionID OR (ConfirmedVersionID IS NULL AND @ConfirmedVersionID IS NULL))
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[DistributedPackageRemoveAllByRequestedVersionID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[DistributedPackageRemoveAllByRequestedVersionID]
GO
CREATE PROCEDURE [dbo].[DistributedPackageRemoveAllByRequestedVersionID]
	@RequestedVersionID	int = NULL
AS
	DELETE	[dbo].[DistributedPackage]
	WHERE	(RequestedVersionID = @RequestedVersionID OR (RequestedVersionID IS NULL AND @RequestedVersionID IS NULL))
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[DistributedPackageRemoveAll]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[DistributedPackageRemoveAll]
GO
CREATE PROCEDURE [dbo].[DistributedPackageRemoveAll]
	
AS
	DELETE	[dbo].[DistributedPackage]
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[DistributionGroupGetByGroupName]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[DistributionGroupGetByGroupName]
GO
CREATE PROCEDURE [dbo].[DistributionGroupGetByGroupName]
	@GroupName		nvarchar(128)
AS
	SELECT	GroupUID,
		GroupName
	FROM	[dbo].[DistributionGroup]
	WHERE	GroupName = @GroupName
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[DistributionGroupGetByGroupUID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[DistributionGroupGetByGroupUID]
GO
CREATE PROCEDURE [dbo].[DistributionGroupGetByGroupUID]
	@GroupUID		binary(16)
AS
	SELECT	GroupUID,
		GroupName
	FROM	[dbo].[DistributionGroup]
	WHERE	GroupUID = @GroupUID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[DistributionGroupGetAll]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[DistributionGroupGetAll]
GO
CREATE PROCEDURE [dbo].[DistributionGroupGetAll]
AS
	SELECT	GroupUID,
		GroupName
	FROM	[dbo].[DistributionGroup]
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[DistributionGroupAdd]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[DistributionGroupAdd]
GO
CREATE PROCEDURE [dbo].[DistributionGroupAdd]
	@GroupUID		binary(16),
	@GroupName		nvarchar(128)
AS
	INSERT INTO  dbo.DistributionGroup (
		GroupUID,
		GroupName
	)
	VALUES (
		@GroupUID,
		@GroupName
	)
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[DistributionGroupSchema]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[DistributionGroupSchema]
GO
CREATE PROCEDURE [dbo].[DistributionGroupSchema]
AS
	SELECT
	'IF OBJECT_ID(''tempdb..#DistributionGroup'') IS NULL' + CAST(0x0A AS CHAR(1)) +
	'	CREATE TABLE #DistributionGroup (' + CAST(0x0A AS CHAR(1)) +
	'		GroupUID		binary(16) NOT NULL,' + CAST(0x0A AS CHAR(1)) +
	'		GroupName		nvarchar(128) COLLATE database_default NOT NULL' + CAST(0x0A AS CHAR(1)) +
	'	)' + CAST(0x0A AS CHAR(1)) +
	'ELSE' + CAST(0x0A AS CHAR(1)) +
	'	DELETE FROM #DistributionGroup' + CAST(0x0A AS CHAR(1)) +
	'' AS SQL
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[DistributionGroupTempAdd]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[DistributionGroupTempAdd]
GO
CREATE PROCEDURE dbo.[DistributionGroupTempAdd]
	@GroupUID		binary(16),
	@GroupName		nvarchar(128)
AS
	INSERT INTO #DistributionGroup (
		GroupUID,
		GroupName
	)
	VALUES (
		@GroupUID,
		@GroupName
	)
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[DistributionGroupAddBatch]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[DistributionGroupAddBatch]
GO
CREATE PROCEDURE dbo.[DistributionGroupAddBatch]
AS
	DECLARE @count int
	INSERT dbo.DistributionGroup (
		GroupUID,
		GroupName
	)
		SELECT	GroupUID,
			GroupName
		FROM #DistributionGroup
	SET @count = @@ROWCOUNT
	DROP TABLE #DistributionGroup	-- Drop temporary table
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[DistributionGroupUpdateByGroupName]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[DistributionGroupUpdateByGroupName]
GO
CREATE PROCEDURE [dbo].[DistributionGroupUpdateByGroupName]
	@GroupName		nvarchar(128),
	@GroupUID		binary(16)
AS
	UPDATE	[dbo].[DistributionGroup]
	SET	GroupUID = @GroupUID
	WHERE	GroupName = @GroupName
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[DistributionGroupUpdateBatchByGroupName]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[DistributionGroupUpdateBatchByGroupName]
GO
CREATE PROCEDURE dbo.[DistributionGroupUpdateBatchByGroupName]
AS
	DECLARE @count int

	CREATE INDEX [TempDistributionGroupGroupName]
		ON #DistributionGroup (GroupName)

	UPDATE	[dbo].[DistributionGroup]
	SET	GroupUID = t.GroupUID
	FROM	#DistributionGroup AS t
	WHERE	DistributionGroup.GroupName = t.GroupName
	SET @count = @@ROWCOUNT
	DROP TABLE #DistributionGroup	-- Drop the temporary table
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[DistributionGroupPutByGroupName]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[DistributionGroupPutByGroupName]
GO
CREATE PROCEDURE [dbo].[DistributionGroupPutByGroupName]
	@GroupName		nvarchar(128),
	@GroupUID		binary(16)
AS
	IF NOT EXISTS(
		SELECT	1
		FROM	dbo.DistributionGroup
		WHERE	GroupName = @GroupName
	)
		EXEC DistributionGroupAdd @GroupUID,
			@GroupName
	ELSE
		EXEC DistributionGroupUpdateByGroupName @GroupName,
			@GroupUID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[DistributionGroupPutBatchByGroupName]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[DistributionGroupPutBatchByGroupName]
GO
CREATE PROCEDURE [dbo].[DistributionGroupPutBatchByGroupName]
AS
	DECLARE @count AS int
	SET @count = 0

	CREATE INDEX [TempDistributionGroupGroupName]
		ON #DistributionGroup (GroupName)

	BEGIN TRANSACTION
	UPDATE [dbo].[DistributionGroup]
		SET	GroupUID = t.GroupUID
		FROM	#DistributionGroup AS t
		WHERE	DistributionGroup.GroupName = t.GroupName
	SET @count = @@ROWCOUNT

	INSERT [dbo].[DistributionGroup] (
		GroupUID,
		GroupName
	)
		SELECT	GroupUID,
			GroupName
		FROM	#DistributionGroup AS t
		WHERE NOT EXISTS(	-- Current record doesn't exist
			SELECT * FROM [dbo].[DistributionGroup]
			WHERE	DistributionGroup.GroupName = t.GroupName
		)
	SET @count = @count + @@ROWCOUNT
	DROP TABLE #DistributionGroup	-- Drop the temporary table
	COMMIT WORK
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[DistributionGroupRemoveBatch]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[DistributionGroupRemoveBatch]
GO

CREATE PROCEDURE [dbo].[DistributionGroupRemoveBatch]
AS

	CREATE INDEX [TempDistributionGroupDistributionGroupRemoveBatch]
		ON #DistributionGroup (GroupName)	

	-- Delete records from DistributionGroup identified by fields of [TempDistributionGroupDistributionGroupRemoveBatch]
	DELETE [dbo].[DistributionGroup]
	WHERE EXISTS(
			SELECT * FROM #DistributionGroup AS t
			WHERE	DistributionGroup.GroupName = t.GroupName
		)
	DROP TABLE #DistributionGroup      -- Drop the temporary table
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[DistributionGroupRemoveByGroupName]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[DistributionGroupRemoveByGroupName]
GO
CREATE PROCEDURE [dbo].[DistributionGroupRemoveByGroupName]
	@GroupName		nvarchar(128)
AS
	-- DistributionGroup deletes cascade to:
	--	DistributionGroupMember by FK_DistributionGroupMember_GroupUID
	DELETE	[dbo].[DistributionGroup]
	WHERE	GroupName = @GroupName
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[DistributionGroupRemoveAll]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[DistributionGroupRemoveAll]
GO
CREATE PROCEDURE [dbo].[DistributionGroupRemoveAll]
	
AS
	DELETE	[dbo].[DistributionGroup]
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[DistributionGroupMemberGetByGroupUIDMemberID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[DistributionGroupMemberGetByGroupUIDMemberID]
GO
CREATE PROCEDURE [dbo].[DistributionGroupMemberGetByGroupUIDMemberID]
	@GroupUID		binary(16),
	@MemberID		binary(16)
AS
	SELECT	GroupUID,
		MemberID,
		MemberType
	FROM	[dbo].[DistributionGroupMember]
	WHERE	GroupUID = @GroupUID
	  AND	MemberID = @MemberID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[DistributionGroupMemberGetAllByGroupUID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[DistributionGroupMemberGetAllByGroupUID]
GO
CREATE PROCEDURE [dbo].[DistributionGroupMemberGetAllByGroupUID]
	@GroupUID		binary(16)
AS
	SELECT	GroupUID,
		MemberID,
		MemberType
	FROM	[dbo].[DistributionGroupMember]
	WHERE	GroupUID = @GroupUID
	ORDER BY MemberID
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[DistributionGroupMemberGetAll]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[DistributionGroupMemberGetAll]
GO
CREATE PROCEDURE [dbo].[DistributionGroupMemberGetAll]
AS
	SELECT	GroupUID,
		MemberID,
		MemberType
	FROM	[dbo].[DistributionGroupMember]
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[DistributionGroupMemberAdd]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[DistributionGroupMemberAdd]
GO
CREATE PROCEDURE [dbo].[DistributionGroupMemberAdd]
	@GroupUID		binary(16),
	@MemberID		binary(16),
	@MemberType		int
AS
	INSERT INTO  dbo.DistributionGroupMember (
		GroupUID,
		MemberID,
		MemberType
	)
	VALUES (
		@GroupUID,
		@MemberID,
		@MemberType
	)
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[DistributionGroupMemberSchema]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[DistributionGroupMemberSchema]
GO
CREATE PROCEDURE [dbo].[DistributionGroupMemberSchema]
AS
	SELECT
	'IF OBJECT_ID(''tempdb..#DistributionGroupMember'') IS NULL' + CAST(0x0A AS CHAR(1)) +
	'	CREATE TABLE #DistributionGroupMember (' + CAST(0x0A AS CHAR(1)) +
	'		GroupUID		binary(16) NOT NULL,' + CAST(0x0A AS CHAR(1)) +
	'		MemberID		binary(16) NOT NULL,' + CAST(0x0A AS CHAR(1)) +
	'		MemberType		int NOT NULL' + CAST(0x0A AS CHAR(1)) +
	'	)' + CAST(0x0A AS CHAR(1)) +
	'ELSE' + CAST(0x0A AS CHAR(1)) +
	'	DELETE FROM #DistributionGroupMember' + CAST(0x0A AS CHAR(1)) +
	'' AS SQL
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[DistributionGroupMemberTempAdd]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[DistributionGroupMemberTempAdd]
GO
CREATE PROCEDURE dbo.[DistributionGroupMemberTempAdd]
	@GroupUID		binary(16),
	@MemberID		binary(16),
	@MemberType		int
AS
	INSERT INTO #DistributionGroupMember (
		GroupUID,
		MemberID,
		MemberType
	)
	VALUES (
		@GroupUID,
		@MemberID,
		@MemberType
	)
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[DistributionGroupMemberAddBatch]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[DistributionGroupMemberAddBatch]
GO
CREATE PROCEDURE dbo.[DistributionGroupMemberAddBatch]
AS
	DECLARE @count int
	INSERT dbo.DistributionGroupMember (
		GroupUID,
		MemberID,
		MemberType
	)
		SELECT	GroupUID,
			MemberID,
			MemberType
		FROM #DistributionGroupMember
	SET @count = @@ROWCOUNT
	DROP TABLE #DistributionGroupMember	-- Drop temporary table
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[DistributionGroupMemberUpdateByGroupUIDMemberID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[DistributionGroupMemberUpdateByGroupUIDMemberID]
GO
CREATE PROCEDURE [dbo].[DistributionGroupMemberUpdateByGroupUIDMemberID]
	@GroupUID		binary(16),
	@MemberID		binary(16),
	@MemberType		int
AS
	UPDATE	[dbo].[DistributionGroupMember]
	SET	MemberType = @MemberType
	WHERE	GroupUID = @GroupUID
	  AND	MemberID = @MemberID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[DistributionGroupMemberUpdateBatchByGroupUIDMemberID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[DistributionGroupMemberUpdateBatchByGroupUIDMemberID]
GO
CREATE PROCEDURE dbo.[DistributionGroupMemberUpdateBatchByGroupUIDMemberID]
AS
	DECLARE @count int

	CREATE INDEX [TempDistributionGroupMemberGroupUIDMemberID]
		ON #DistributionGroupMember (GroupUID, MemberID)

	UPDATE	[dbo].[DistributionGroupMember]
	SET	MemberType = t.MemberType
	FROM	#DistributionGroupMember AS t
	WHERE	DistributionGroupMember.GroupUID = t.GroupUID
	  AND	DistributionGroupMember.MemberID = t.MemberID
	SET @count = @@ROWCOUNT
	DROP TABLE #DistributionGroupMember	-- Drop the temporary table
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[DistributionGroupMemberPutByGroupUIDMemberID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[DistributionGroupMemberPutByGroupUIDMemberID]
GO
CREATE PROCEDURE [dbo].[DistributionGroupMemberPutByGroupUIDMemberID]
	@GroupUID		binary(16),
	@MemberID		binary(16),
	@MemberType		int
AS
	IF NOT EXISTS(
		SELECT	1
		FROM	dbo.DistributionGroupMember
		WHERE	GroupUID = @GroupUID
		  AND	MemberID = @MemberID
	)
		EXEC DistributionGroupMemberAdd @GroupUID,
			@MemberID,
			@MemberType
	ELSE
		EXEC DistributionGroupMemberUpdateByGroupUIDMemberID @GroupUID,
			@MemberID,
			@MemberType
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[DistributionGroupMemberPutBatchByGroupUIDMemberID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[DistributionGroupMemberPutBatchByGroupUIDMemberID]
GO
CREATE PROCEDURE [dbo].[DistributionGroupMemberPutBatchByGroupUIDMemberID]
AS
	DECLARE @count AS int
	SET @count = 0

	CREATE INDEX [TempDistributionGroupMemberGroupUIDMemberID]
		ON #DistributionGroupMember (GroupUID, MemberID)

	BEGIN TRANSACTION
	UPDATE [dbo].[DistributionGroupMember]
		SET	MemberType = t.MemberType
		FROM	#DistributionGroupMember AS t
		WHERE	DistributionGroupMember.GroupUID = t.GroupUID
		  AND	DistributionGroupMember.MemberID = t.MemberID
	SET @count = @@ROWCOUNT

	INSERT [dbo].[DistributionGroupMember] (
		GroupUID,
		MemberID,
		MemberType
	)
		SELECT	GroupUID,
			MemberID,
			MemberType
		FROM	#DistributionGroupMember AS t
		WHERE NOT EXISTS(	-- Current record doesn't exist
			SELECT * FROM [dbo].[DistributionGroupMember]
			WHERE	DistributionGroupMember.GroupUID = t.GroupUID
			  AND	DistributionGroupMember.MemberID = t.MemberID
		)
	SET @count = @count + @@ROWCOUNT
	DROP TABLE #DistributionGroupMember	-- Drop the temporary table
	COMMIT WORK
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[DistributionGroupMemberRemoveBatch]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[DistributionGroupMemberRemoveBatch]
GO

CREATE PROCEDURE [dbo].[DistributionGroupMemberRemoveBatch]
AS

	CREATE INDEX [TempDistributionGroupMemberDistributionGroupMemberRemoveBatch]
		ON #DistributionGroupMember (GroupUID, MemberID)	

	-- Delete records from DistributionGroupMember identified by fields of [TempDistributionGroupMemberDistributionGroupMemberRemoveBatch]
	DELETE [dbo].[DistributionGroupMember]
	WHERE EXISTS(
			SELECT * FROM #DistributionGroupMember AS t
			WHERE	DistributionGroupMember.GroupUID = t.GroupUID
			  AND	DistributionGroupMember.MemberID = t.MemberID
		)
	DROP TABLE #DistributionGroupMember      -- Drop the temporary table
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[DistributionGroupMemberRemoveByGroupUIDMemberID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[DistributionGroupMemberRemoveByGroupUIDMemberID]
GO
CREATE PROCEDURE [dbo].[DistributionGroupMemberRemoveByGroupUIDMemberID]
	@GroupUID		binary(16),
	@MemberID		binary(16)
AS
	DELETE	[dbo].[DistributionGroupMember]
	WHERE	GroupUID = @GroupUID
	  AND	MemberID = @MemberID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[DistributionGroupMemberRemoveAllByMemberID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[DistributionGroupMemberRemoveAllByMemberID]
GO
CREATE PROCEDURE [dbo].[DistributionGroupMemberRemoveAllByMemberID]
	@MemberID		binary(16)
AS
	DELETE	[dbo].[DistributionGroupMember]
	WHERE	MemberID = @MemberID
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[DistributionGroupMemberRemoveAll]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[DistributionGroupMemberRemoveAll]
GO
CREATE PROCEDURE [dbo].[DistributionGroupMemberRemoveAll]
	
AS
	DELETE	[dbo].[DistributionGroupMember]
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[LicenseModelGetByName]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[LicenseModelGetByName]
GO
CREATE PROCEDURE [dbo].[LicenseModelGetByName]
	@Name			nvarchar(256)
AS
	SELECT	ModelID,
		[Name]
	FROM	[dbo].[LicenseModel]
	WHERE	[Name] = @Name
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[LicenseModelGetByID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[LicenseModelGetByID]
GO
CREATE PROCEDURE [dbo].[LicenseModelGetByID]
	@ModelID		int
AS
	SELECT	ModelID,
		[Name]
	FROM	[dbo].[LicenseModel]
	WHERE	ModelID = @ModelID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[LicenseModelGetAll]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[LicenseModelGetAll]
GO
CREATE PROCEDURE [dbo].[LicenseModelGetAll]
AS
	SELECT	ModelID,
		[Name]
	FROM	[dbo].[LicenseModel]
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[LicenseModelAdd]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[LicenseModelAdd]
GO
CREATE PROCEDURE [dbo].[LicenseModelAdd]
	@Name			nvarchar(256)
AS
	INSERT INTO  dbo.LicenseModel (
		[Name]
	)
	VALUES (
		@Name
	)
	RETURN SCOPE_IDENTITY()
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[LicenseModelBind]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[LicenseModelBind]
GO
CREATE PROCEDURE [dbo].[LicenseModelBind]
	@Name			nvarchar(256)
AS
	DECLARE	@ID	int

	SELECT	@ID = ModelID
	FROM	[dbo].[LicenseModel]
	WHERE	[Name] = @Name

	IF @ID IS NULL
		EXEC @ID = LicenseModelAdd @Name

	RETURN @ID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[LicenseModelSchema]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[LicenseModelSchema]
GO
CREATE PROCEDURE [dbo].[LicenseModelSchema]
AS
	SELECT
	'IF OBJECT_ID(''tempdb..#LicenseModel'') IS NULL' + CAST(0x0A AS CHAR(1)) +
	'	CREATE TABLE #LicenseModel (' + CAST(0x0A AS CHAR(1)) +
	'		ModelID			int NULL,' + CAST(0x0A AS CHAR(1)) +
	'		[Name]			nvarchar(256) COLLATE database_default NOT NULL' + CAST(0x0A AS CHAR(1)) +
	'	)' + CAST(0x0A AS CHAR(1)) +
	'ELSE' + CAST(0x0A AS CHAR(1)) +
	'	DELETE FROM #LicenseModel' + CAST(0x0A AS CHAR(1)) +
	'' AS SQL
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[LicenseModelTempAdd]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[LicenseModelTempAdd]
GO
CREATE PROCEDURE dbo.[LicenseModelTempAdd]
	@ModelID		int,
	@Name			nvarchar(256)
AS
	INSERT INTO #LicenseModel (
		ModelID,
		[Name]
	)
	VALUES (
		@ModelID,
		@Name
	)
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[LicenseModelAddBatch]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[LicenseModelAddBatch]
GO
CREATE PROCEDURE dbo.[LicenseModelAddBatch]
AS
	DECLARE @count int
	INSERT dbo.LicenseModel (
		[Name]
	)
		SELECT	[Name]
		FROM #LicenseModel
	SET @count = @@ROWCOUNT
	DROP TABLE #LicenseModel	-- Drop temporary table
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[LicenseModelUpdateByID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[LicenseModelUpdateByID]
GO
CREATE PROCEDURE [dbo].[LicenseModelUpdateByID]
	@ModelID		int,
	@Name			nvarchar(256)
AS
	DECLARE	@ID	int
	SET @ID = 0

	UPDATE	[dbo].[LicenseModel]
	SET	@ID = ModelID,
		[Name] = @Name
	WHERE	ModelID = @ModelID
	RETURN @ID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[LicenseModelUpdateBatchByID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[LicenseModelUpdateBatchByID]
GO
CREATE PROCEDURE dbo.[LicenseModelUpdateBatchByID]
AS
	DECLARE @count int

	CREATE INDEX [TempLicenseModelID]
		ON #LicenseModel (ModelID)

	UPDATE	[dbo].[LicenseModel]
	SET	[Name] = t.[Name]
	FROM	#LicenseModel AS t
	WHERE	LicenseModel.ModelID = t.ModelID
	SET @count = @@ROWCOUNT
	DROP TABLE #LicenseModel	-- Drop the temporary table
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[LicenseModelPutByName]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[LicenseModelPutByName]
GO
CREATE PROCEDURE [dbo].[LicenseModelPutByName]
	@Name			nvarchar(256)
AS
	DECLARE @ID	int

	SELECT	@ID = ModelID
	FROM	LicenseModel
	WHERE	[Name] = @Name

	IF @ID IS NULL
		EXEC @ID = LicenseModelAdd @Name

	RETURN @ID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[LicenseModelPutBatchByName]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[LicenseModelPutBatchByName]
GO
CREATE PROCEDURE [dbo].[LicenseModelPutBatchByName]
AS
	DECLARE @count AS int
	SET @count = 0

	CREATE INDEX [TempLicenseModelName]
		ON #LicenseModel ([Name])

	BEGIN TRANSACTION

	INSERT [dbo].[LicenseModel] (
		[Name]
	)
		SELECT	[Name]
		FROM	#LicenseModel AS t
		WHERE NOT EXISTS(	-- Current record doesn't exist
			SELECT * FROM [dbo].[LicenseModel]
			WHERE	LicenseModel.[Name] = t.[Name]
		)
	SET @count = @count + @@ROWCOUNT
	DROP TABLE #LicenseModel	-- Drop the temporary table
	COMMIT WORK
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[LicenseModelRemoveBatch]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[LicenseModelRemoveBatch]
GO

CREATE PROCEDURE [dbo].[LicenseModelRemoveBatch]
AS

	CREATE INDEX [TempLicenseModelLicenseModelRemoveBatch]
		ON #LicenseModel (ModelID)	

	-- Delete records from LicenseModel identified by fields of [TempLicenseModelLicenseModelRemoveBatch]
	DELETE [dbo].[LicenseModel]
	WHERE EXISTS(
			SELECT * FROM #LicenseModel AS t
			WHERE	LicenseModel.ModelID = t.ModelID
		)
	DROP TABLE #LicenseModel      -- Drop the temporary table
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[LicenseModelRemoveByName]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[LicenseModelRemoveByName]
GO
CREATE PROCEDURE [dbo].[LicenseModelRemoveByName]
	@Name			nvarchar(256)
AS
	-- LicenseModel deletes cascade to:
	--	SoftwareProduct by FK_SoftwareProduct_Model
	--		LicenseAllocation by FK_LicenseAllocation_SoftwareProductID
	--		LicensePurchase by FK_LicensePurchase
	--		ProductContainsSoftware by FK_ProductContains_SoftwareProductID
	DELETE	[dbo].[LicenseModel]
	WHERE	[Name] = @Name
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[LicenseModelRemoveByID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[LicenseModelRemoveByID]
GO
CREATE PROCEDURE [dbo].[LicenseModelRemoveByID]
	@ModelID		int
AS
	-- LicenseModel deletes cascade to:
	--	SoftwareProduct by FK_SoftwareProduct_Model
	--		LicenseAllocation by FK_LicenseAllocation_SoftwareProductID
	--		LicensePurchase by FK_LicensePurchase
	--		ProductContainsSoftware by FK_ProductContains_SoftwareProductID
	DELETE	[dbo].[LicenseModel]
	WHERE	ModelID = @ModelID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[LicenseModelRemoveAll]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[LicenseModelRemoveAll]
GO
CREATE PROCEDURE [dbo].[LicenseModelRemoveAll]
	
AS
	DELETE	[dbo].[LicenseModel]
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[SoftwarePublisherGetByName]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[SoftwarePublisherGetByName]
GO
CREATE PROCEDURE [dbo].[SoftwarePublisherGetByName]
	@Name			nvarchar(256)
AS
	SELECT	PublisherID,
		[Name],
		SupportURL,
		SupportPhone,
		ContactName,
		Comments
	FROM	[dbo].[SoftwarePublisher]
	WHERE	[Name] = @Name
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[SoftwarePublisherGetByID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[SoftwarePublisherGetByID]
GO
CREATE PROCEDURE [dbo].[SoftwarePublisherGetByID]
	@PublisherID		int
AS
	SELECT	PublisherID,
		[Name],
		SupportURL,
		SupportPhone,
		ContactName,
		Comments
	FROM	[dbo].[SoftwarePublisher]
	WHERE	PublisherID = @PublisherID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[SoftwarePublisherGetAll]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[SoftwarePublisherGetAll]
GO
CREATE PROCEDURE [dbo].[SoftwarePublisherGetAll]
AS
	SELECT	PublisherID,
		[Name],
		SupportURL,
		SupportPhone,
		ContactName,
		Comments
	FROM	[dbo].[SoftwarePublisher]
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[SoftwarePublisherAdd]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[SoftwarePublisherAdd]
GO
CREATE PROCEDURE [dbo].[SoftwarePublisherAdd]
	@Name			nvarchar(256),
	@SupportURL		nvarchar(256) = '',
	@SupportPhone		nvarchar(256) = '',
	@ContactName		nvarchar(256) = '',
	@Comments		nvarchar(512) = ''
AS
	INSERT INTO  dbo.SoftwarePublisher (
		[Name],
		SupportURL,
		SupportPhone,
		ContactName,
		Comments
	)
	VALUES (
		@Name,
		@SupportURL,
		@SupportPhone,
		@ContactName,
		@Comments
	)
	RETURN SCOPE_IDENTITY()
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[SoftwarePublisherBind]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[SoftwarePublisherBind]
GO
CREATE PROCEDURE [dbo].[SoftwarePublisherBind]
	@Name			nvarchar(256),
	@SupportURL		nvarchar(256) = '',
	@SupportPhone		nvarchar(256) = '',
	@ContactName		nvarchar(256) = '',
	@Comments		nvarchar(512) = ''
AS
	DECLARE	@ID	int

	SELECT	@ID = PublisherID
	FROM	[dbo].[SoftwarePublisher]
	WHERE	[Name] = @Name

	IF @ID IS NULL
		EXEC @ID = SoftwarePublisherAdd @Name,
			@SupportURL,
			@SupportPhone,
			@ContactName,
			@Comments

	RETURN @ID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[SoftwarePublisherSchema]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[SoftwarePublisherSchema]
GO
CREATE PROCEDURE [dbo].[SoftwarePublisherSchema]
AS
	SELECT
	'IF OBJECT_ID(''tempdb..#SoftwarePublisher'') IS NULL' + CAST(0x0A AS CHAR(1)) +
	'	CREATE TABLE #SoftwarePublisher (' + CAST(0x0A AS CHAR(1)) +
	'		PublisherID		int NULL,' + CAST(0x0A AS CHAR(1)) +
	'		[Name]			nvarchar(256) COLLATE database_default NOT NULL,' + CAST(0x0A AS CHAR(1)) +
	'		SupportURL		nvarchar(256) COLLATE database_default NOT NULL DEFAULT '''',' + CAST(0x0A AS CHAR(1)) +
	'		SupportPhone		nvarchar(256) COLLATE database_default NOT NULL DEFAULT '''',' + CAST(0x0A AS CHAR(1)) +
	'		ContactName		nvarchar(256) COLLATE database_default NOT NULL DEFAULT '''',' + CAST(0x0A AS CHAR(1)) +
	'		Comments		nvarchar(512) COLLATE database_default NOT NULL DEFAULT ''''' + CAST(0x0A AS CHAR(1)) +
	'	)' + CAST(0x0A AS CHAR(1)) +
	'ELSE' + CAST(0x0A AS CHAR(1)) +
	'	DELETE FROM #SoftwarePublisher' + CAST(0x0A AS CHAR(1)) +
	'' AS SQL
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[SoftwarePublisherTempAdd]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[SoftwarePublisherTempAdd]
GO
CREATE PROCEDURE dbo.[SoftwarePublisherTempAdd]
	@PublisherID		int,
	@Name			nvarchar(256),
	@SupportURL		nvarchar(256) = '',
	@SupportPhone		nvarchar(256) = '',
	@ContactName		nvarchar(256) = '',
	@Comments		nvarchar(512) = ''
AS
	INSERT INTO #SoftwarePublisher (
		PublisherID,
		[Name],
		SupportURL,
		SupportPhone,
		ContactName,
		Comments
	)
	VALUES (
		@PublisherID,
		@Name,
		@SupportURL,
		@SupportPhone,
		@ContactName,
		@Comments
	)
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[SoftwarePublisherAddBatch]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[SoftwarePublisherAddBatch]
GO
CREATE PROCEDURE dbo.[SoftwarePublisherAddBatch]
AS
	DECLARE @count int
	INSERT dbo.SoftwarePublisher (
		[Name],
		SupportURL,
		SupportPhone,
		ContactName,
		Comments
	)
		SELECT	[Name],
			SupportURL,
			SupportPhone,
			ContactName,
			Comments
		FROM #SoftwarePublisher
	SET @count = @@ROWCOUNT
	DROP TABLE #SoftwarePublisher	-- Drop temporary table
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[SoftwarePublisherUpdateByID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[SoftwarePublisherUpdateByID]
GO
CREATE PROCEDURE [dbo].[SoftwarePublisherUpdateByID]
	@PublisherID		int,
	@Name			nvarchar(256),
	@SupportURL		nvarchar(256) = '',
	@SupportPhone		nvarchar(256) = '',
	@ContactName		nvarchar(256) = '',
	@Comments		nvarchar(512) = ''
AS
	DECLARE	@ID	int
	SET @ID = 0

	UPDATE	[dbo].[SoftwarePublisher]
	SET	@ID = PublisherID,
		[Name] = @Name,
		SupportURL = @SupportURL,
		SupportPhone = @SupportPhone,
		ContactName = @ContactName,
		Comments = @Comments
	WHERE	PublisherID = @PublisherID
	RETURN @ID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[SoftwarePublisherUpdateBatchByID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[SoftwarePublisherUpdateBatchByID]
GO
CREATE PROCEDURE dbo.[SoftwarePublisherUpdateBatchByID]
AS
	DECLARE @count int

	CREATE INDEX [TempSoftwarePublisherID]
		ON #SoftwarePublisher (PublisherID)

	UPDATE	[dbo].[SoftwarePublisher]
	SET	[Name] = t.[Name],
		SupportURL = t.SupportURL,
		SupportPhone = t.SupportPhone,
		ContactName = t.ContactName,
		Comments = t.Comments
	FROM	#SoftwarePublisher AS t
	WHERE	SoftwarePublisher.PublisherID = t.PublisherID
	SET @count = @@ROWCOUNT
	DROP TABLE #SoftwarePublisher	-- Drop the temporary table
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[SoftwarePublisherUpdateByName]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[SoftwarePublisherUpdateByName]
GO
CREATE PROCEDURE [dbo].[SoftwarePublisherUpdateByName]
	@Name			nvarchar(256),
	@SupportURL		nvarchar(256) = '',
	@SupportPhone		nvarchar(256) = '',
	@ContactName		nvarchar(256) = '',
	@Comments		nvarchar(512) = ''
AS
	DECLARE	@ID	int
	SET @ID = 0

	UPDATE	[dbo].[SoftwarePublisher]
	SET	@ID = PublisherID,
		SupportURL = @SupportURL,
		SupportPhone = @SupportPhone,
		ContactName = @ContactName,
		Comments = @Comments
	WHERE	[Name] = @Name
	RETURN @ID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[SoftwarePublisherUpdateBatchByName]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[SoftwarePublisherUpdateBatchByName]
GO
CREATE PROCEDURE dbo.[SoftwarePublisherUpdateBatchByName]
AS
	DECLARE @count int

	CREATE INDEX [TempSoftwarePublisherName]
		ON #SoftwarePublisher ([Name])

	UPDATE	[dbo].[SoftwarePublisher]
	SET	SupportURL = t.SupportURL,
		SupportPhone = t.SupportPhone,
		ContactName = t.ContactName,
		Comments = t.Comments
	FROM	#SoftwarePublisher AS t
	WHERE	SoftwarePublisher.[Name] = t.[Name]
	SET @count = @@ROWCOUNT
	DROP TABLE #SoftwarePublisher	-- Drop the temporary table
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[SoftwarePublisherPutByName]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[SoftwarePublisherPutByName]
GO
CREATE PROCEDURE [dbo].[SoftwarePublisherPutByName]
	@Name			nvarchar(256),
	@SupportURL		nvarchar(256) = '',
	@SupportPhone		nvarchar(256) = '',
	@ContactName		nvarchar(256) = '',
	@Comments		nvarchar(512) = ''
AS
	DECLARE @ID	int

	SELECT	@ID = PublisherID
	FROM	SoftwarePublisher
	WHERE	[Name] = @Name

	IF @ID IS NULL
		EXEC @ID = SoftwarePublisherAdd @Name,
			@SupportURL,
			@SupportPhone,
			@ContactName,
			@Comments
	ELSE
		EXEC SoftwarePublisherUpdateByName @Name,
			@SupportURL,
			@SupportPhone,
			@ContactName,
			@Comments

	RETURN @ID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[SoftwarePublisherPutBatchByName]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[SoftwarePublisherPutBatchByName]
GO
CREATE PROCEDURE [dbo].[SoftwarePublisherPutBatchByName]
AS
	DECLARE @count AS int
	SET @count = 0

	CREATE INDEX [TempSoftwarePublisherName]
		ON #SoftwarePublisher ([Name])

	BEGIN TRANSACTION
	UPDATE [dbo].[SoftwarePublisher]
		SET	SupportURL = t.SupportURL,
			SupportPhone = t.SupportPhone,
			ContactName = t.ContactName,
			Comments = t.Comments
		FROM	#SoftwarePublisher AS t
		WHERE	SoftwarePublisher.[Name] = t.[Name]
	SET @count = @@ROWCOUNT

	INSERT [dbo].[SoftwarePublisher] (
		[Name],
		SupportURL,
		SupportPhone,
		ContactName,
		Comments
	)
		SELECT	[Name],
			SupportURL,
			SupportPhone,
			ContactName,
			Comments
		FROM	#SoftwarePublisher AS t
		WHERE NOT EXISTS(	-- Current record doesn't exist
			SELECT * FROM [dbo].[SoftwarePublisher]
			WHERE	SoftwarePublisher.[Name] = t.[Name]
		)
	SET @count = @count + @@ROWCOUNT
	DROP TABLE #SoftwarePublisher	-- Drop the temporary table
	COMMIT WORK
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[SoftwarePublisherRemoveBatch]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[SoftwarePublisherRemoveBatch]
GO

CREATE PROCEDURE [dbo].[SoftwarePublisherRemoveBatch]
AS

	CREATE INDEX [TempSoftwarePublisherSoftwarePublisherRemoveBatch]
		ON #SoftwarePublisher (PublisherID)	

	-- Delete records from SoftwarePublisher identified by fields of [TempSoftwarePublisherSoftwarePublisherRemoveBatch]
	DELETE [dbo].[SoftwarePublisher]
	WHERE EXISTS(
			SELECT * FROM #SoftwarePublisher AS t
			WHERE	SoftwarePublisher.PublisherID = t.PublisherID
		)
	DROP TABLE #SoftwarePublisher      -- Drop the temporary table
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[SoftwarePublisherRemoveByName]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[SoftwarePublisherRemoveByName]
GO
CREATE PROCEDURE [dbo].[SoftwarePublisherRemoveByName]
	@Name			nvarchar(256)
AS
	-- SoftwarePublisher deletes cascade to:
	--	SoftwareProduct by FK_SoftwareProduct_Publisher
	--		LicenseAllocation by FK_LicenseAllocation_SoftwareProductID
	--		LicensePurchase by FK_LicensePurchase
	--		ProductContainsSoftware by FK_ProductContains_SoftwareProductID
	DELETE	[dbo].[SoftwarePublisher]
	WHERE	[Name] = @Name
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[SoftwarePublisherRemoveByID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[SoftwarePublisherRemoveByID]
GO
CREATE PROCEDURE [dbo].[SoftwarePublisherRemoveByID]
	@PublisherID		int
AS
	-- SoftwarePublisher deletes cascade to:
	--	SoftwareProduct by FK_SoftwareProduct_Publisher
	--		LicenseAllocation by FK_LicenseAllocation_SoftwareProductID
	--		LicensePurchase by FK_LicensePurchase
	--		ProductContainsSoftware by FK_ProductContains_SoftwareProductID
	DELETE	[dbo].[SoftwarePublisher]
	WHERE	PublisherID = @PublisherID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[SoftwarePublisherRemoveAll]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[SoftwarePublisherRemoveAll]
GO
CREATE PROCEDURE [dbo].[SoftwarePublisherRemoveAll]
	
AS
	DELETE	[dbo].[SoftwarePublisher]
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[SoftwareResellerGetByName]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[SoftwareResellerGetByName]
GO
CREATE PROCEDURE [dbo].[SoftwareResellerGetByName]
	@Name			nvarchar(256)
AS
	SELECT	ResellerID,
		[Name],
		ContactName,
		ContactPhone,
		Comments
	FROM	[dbo].[SoftwareReseller]
	WHERE	[Name] = @Name
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[SoftwareResellerGetAll]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[SoftwareResellerGetAll]
GO
CREATE PROCEDURE [dbo].[SoftwareResellerGetAll]
AS
	SELECT	ResellerID,
		[Name],
		ContactName,
		ContactPhone,
		Comments
	FROM	[dbo].[SoftwareReseller]
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[SoftwareResellerAdd]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[SoftwareResellerAdd]
GO
CREATE PROCEDURE [dbo].[SoftwareResellerAdd]
	@Name			nvarchar(256),
	@ContactName		nvarchar(256) = '',
	@ContactPhone		nvarchar(256) = '',
	@Comments		nvarchar(512) = ''
AS
	INSERT INTO  dbo.SoftwareReseller (
		[Name],
		ContactName,
		ContactPhone,
		Comments
	)
	VALUES (
		@Name,
		@ContactName,
		@ContactPhone,
		@Comments
	)
	RETURN SCOPE_IDENTITY()
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[SoftwareResellerBind]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[SoftwareResellerBind]
GO
CREATE PROCEDURE [dbo].[SoftwareResellerBind]
	@Name			nvarchar(256),
	@ContactName		nvarchar(256) = '',
	@ContactPhone		nvarchar(256) = '',
	@Comments		nvarchar(512) = ''
AS
	DECLARE	@ID	int

	SELECT	@ID = ResellerID
	FROM	[dbo].[SoftwareReseller]
	WHERE	[Name] = @Name

	IF @ID IS NULL
		EXEC @ID = SoftwareResellerAdd @Name,
			@ContactName,
			@ContactPhone,
			@Comments

	RETURN @ID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[SoftwareResellerSchema]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[SoftwareResellerSchema]
GO
CREATE PROCEDURE [dbo].[SoftwareResellerSchema]
AS
	SELECT
	'IF OBJECT_ID(''tempdb..#SoftwareReseller'') IS NULL' + CAST(0x0A AS CHAR(1)) +
	'	CREATE TABLE #SoftwareReseller (' + CAST(0x0A AS CHAR(1)) +
	'		ResellerID		int NULL,' + CAST(0x0A AS CHAR(1)) +
	'		[Name]			nvarchar(256) COLLATE database_default NOT NULL,' + CAST(0x0A AS CHAR(1)) +
	'		ContactName		nvarchar(256) COLLATE database_default NOT NULL DEFAULT '''',' + CAST(0x0A AS CHAR(1)) +
	'		ContactPhone		nvarchar(256) COLLATE database_default NOT NULL DEFAULT '''',' + CAST(0x0A AS CHAR(1)) +
	'		Comments		nvarchar(512) COLLATE database_default NOT NULL DEFAULT ''''' + CAST(0x0A AS CHAR(1)) +
	'	)' + CAST(0x0A AS CHAR(1)) +
	'ELSE' + CAST(0x0A AS CHAR(1)) +
	'	DELETE FROM #SoftwareReseller' + CAST(0x0A AS CHAR(1)) +
	'' AS SQL
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[SoftwareResellerTempAdd]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[SoftwareResellerTempAdd]
GO
CREATE PROCEDURE dbo.[SoftwareResellerTempAdd]
	@ResellerID		int,
	@Name			nvarchar(256),
	@ContactName		nvarchar(256) = '',
	@ContactPhone		nvarchar(256) = '',
	@Comments		nvarchar(512) = ''
AS
	INSERT INTO #SoftwareReseller (
		ResellerID,
		[Name],
		ContactName,
		ContactPhone,
		Comments
	)
	VALUES (
		@ResellerID,
		@Name,
		@ContactName,
		@ContactPhone,
		@Comments
	)
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[SoftwareResellerAddBatch]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[SoftwareResellerAddBatch]
GO
CREATE PROCEDURE dbo.[SoftwareResellerAddBatch]
AS
	DECLARE @count int
	INSERT dbo.SoftwareReseller (
		[Name],
		ContactName,
		ContactPhone,
		Comments
	)
		SELECT	[Name],
			ContactName,
			ContactPhone,
			Comments
		FROM #SoftwareReseller
	SET @count = @@ROWCOUNT
	DROP TABLE #SoftwareReseller	-- Drop temporary table
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[SoftwareResellerUpdateByID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[SoftwareResellerUpdateByID]
GO
CREATE PROCEDURE [dbo].[SoftwareResellerUpdateByID]
	@ResellerID		int,
	@Name			nvarchar(256),
	@ContactName		nvarchar(256) = '',
	@ContactPhone		nvarchar(256) = '',
	@Comments		nvarchar(512) = ''
AS
	DECLARE	@ID	int
	SET @ID = 0

	UPDATE	[dbo].[SoftwareReseller]
	SET	@ID = ResellerID,
		[Name] = @Name,
		ContactName = @ContactName,
		ContactPhone = @ContactPhone,
		Comments = @Comments
	WHERE	ResellerID = @ResellerID
	RETURN @ID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[SoftwareResellerUpdateBatchByID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[SoftwareResellerUpdateBatchByID]
GO
CREATE PROCEDURE dbo.[SoftwareResellerUpdateBatchByID]
AS
	DECLARE @count int

	CREATE INDEX [TempSoftwareResellerID]
		ON #SoftwareReseller (ResellerID)

	UPDATE	[dbo].[SoftwareReseller]
	SET	[Name] = t.[Name],
		ContactName = t.ContactName,
		ContactPhone = t.ContactPhone,
		Comments = t.Comments
	FROM	#SoftwareReseller AS t
	WHERE	SoftwareReseller.ResellerID = t.ResellerID
	SET @count = @@ROWCOUNT
	DROP TABLE #SoftwareReseller	-- Drop the temporary table
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[SoftwareResellerUpdateByName]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[SoftwareResellerUpdateByName]
GO
CREATE PROCEDURE [dbo].[SoftwareResellerUpdateByName]
	@Name			nvarchar(256),
	@ContactName		nvarchar(256) = '',
	@ContactPhone		nvarchar(256) = '',
	@Comments		nvarchar(512) = ''
AS
	DECLARE	@ID	int
	SET @ID = 0

	UPDATE	[dbo].[SoftwareReseller]
	SET	@ID = ResellerID,
		ContactName = @ContactName,
		ContactPhone = @ContactPhone,
		Comments = @Comments
	WHERE	[Name] = @Name
	RETURN @ID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[SoftwareResellerUpdateBatchByName]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[SoftwareResellerUpdateBatchByName]
GO
CREATE PROCEDURE dbo.[SoftwareResellerUpdateBatchByName]
AS
	DECLARE @count int

	CREATE INDEX [TempSoftwareResellerName]
		ON #SoftwareReseller ([Name])

	UPDATE	[dbo].[SoftwareReseller]
	SET	ContactName = t.ContactName,
		ContactPhone = t.ContactPhone,
		Comments = t.Comments
	FROM	#SoftwareReseller AS t
	WHERE	SoftwareReseller.[Name] = t.[Name]
	SET @count = @@ROWCOUNT
	DROP TABLE #SoftwareReseller	-- Drop the temporary table
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[SoftwareResellerPutByName]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[SoftwareResellerPutByName]
GO
CREATE PROCEDURE [dbo].[SoftwareResellerPutByName]
	@Name			nvarchar(256),
	@ContactName		nvarchar(256) = '',
	@ContactPhone		nvarchar(256) = '',
	@Comments		nvarchar(512) = ''
AS
	DECLARE @ID	int

	SELECT	@ID = ResellerID
	FROM	SoftwareReseller
	WHERE	[Name] = @Name

	IF @ID IS NULL
		EXEC @ID = SoftwareResellerAdd @Name,
			@ContactName,
			@ContactPhone,
			@Comments
	ELSE
		EXEC SoftwareResellerUpdateByName @Name,
			@ContactName,
			@ContactPhone,
			@Comments

	RETURN @ID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[SoftwareResellerPutBatchByName]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[SoftwareResellerPutBatchByName]
GO
CREATE PROCEDURE [dbo].[SoftwareResellerPutBatchByName]
AS
	DECLARE @count AS int
	SET @count = 0

	CREATE INDEX [TempSoftwareResellerName]
		ON #SoftwareReseller ([Name])

	BEGIN TRANSACTION
	UPDATE [dbo].[SoftwareReseller]
		SET	ContactName = t.ContactName,
			ContactPhone = t.ContactPhone,
			Comments = t.Comments
		FROM	#SoftwareReseller AS t
		WHERE	SoftwareReseller.[Name] = t.[Name]
	SET @count = @@ROWCOUNT

	INSERT [dbo].[SoftwareReseller] (
		[Name],
		ContactName,
		ContactPhone,
		Comments
	)
		SELECT	[Name],
			ContactName,
			ContactPhone,
			Comments
		FROM	#SoftwareReseller AS t
		WHERE NOT EXISTS(	-- Current record doesn't exist
			SELECT * FROM [dbo].[SoftwareReseller]
			WHERE	SoftwareReseller.[Name] = t.[Name]
		)
	SET @count = @count + @@ROWCOUNT
	DROP TABLE #SoftwareReseller	-- Drop the temporary table
	COMMIT WORK
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[SoftwareResellerRemoveBatch]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[SoftwareResellerRemoveBatch]
GO

CREATE PROCEDURE [dbo].[SoftwareResellerRemoveBatch]
AS

	CREATE INDEX [TempSoftwareResellerSoftwareResellerRemoveBatch]
		ON #SoftwareReseller (ResellerID)	

	-- Delete records from SoftwareReseller identified by fields of [TempSoftwareResellerSoftwareResellerRemoveBatch]
	DELETE [dbo].[SoftwareReseller]
	WHERE EXISTS(
			SELECT * FROM #SoftwareReseller AS t
			WHERE	SoftwareReseller.ResellerID = t.ResellerID
		)
	DROP TABLE #SoftwareReseller      -- Drop the temporary table
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[SoftwareResellerRemoveByName]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[SoftwareResellerRemoveByName]
GO
CREATE PROCEDURE [dbo].[SoftwareResellerRemoveByName]
	@Name			nvarchar(256)
AS
	-- SoftwareReseller deletes cascade to:
	--	LicensePurchase by FK_LicensePurchase_SoftwareReseller
	DELETE	[dbo].[SoftwareReseller]
	WHERE	[Name] = @Name
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[SoftwareResellerRemoveByID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[SoftwareResellerRemoveByID]
GO
CREATE PROCEDURE [dbo].[SoftwareResellerRemoveByID]
	@ResellerID		int
AS
	-- SoftwareReseller deletes cascade to:
	--	LicensePurchase by FK_LicensePurchase_SoftwareReseller
	DELETE	[dbo].[SoftwareReseller]
	WHERE	ResellerID = @ResellerID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[SoftwareResellerRemoveAll]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[SoftwareResellerRemoveAll]
GO
CREATE PROCEDURE [dbo].[SoftwareResellerRemoveAll]
	
AS
	DELETE	[dbo].[SoftwareReseller]
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[SoftwareProductGetByProductName]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[SoftwareProductGetByProductName]
GO
CREATE PROCEDURE [dbo].[SoftwareProductGetByProductName]
	@ProductName		nvarchar(256)
AS
	SELECT	SoftwareProductID,
		ProductName,
		ModelID,
		TrackedByID,
		PublisherID,
		Agreement,
		Comments
	FROM	[dbo].[SoftwareProduct]
	WHERE	ProductName = @ProductName
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[SoftwareProductGetByID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[SoftwareProductGetByID]
GO
CREATE PROCEDURE [dbo].[SoftwareProductGetByID]
	@SoftwareProductID	int
AS
	SELECT	SoftwareProductID,
		ProductName,
		ModelID,
		TrackedByID,
		PublisherID,
		Agreement,
		Comments
	FROM	[dbo].[SoftwareProduct]
	WHERE	SoftwareProductID = @SoftwareProductID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[SoftwareProductGetAllByModelID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[SoftwareProductGetAllByModelID]
GO
CREATE PROCEDURE [dbo].[SoftwareProductGetAllByModelID]
	@ModelID		int
AS
	SELECT	SoftwareProductID,
		ProductName,
		ModelID,
		TrackedByID,
		PublisherID,
		Agreement,
		Comments
	FROM	[dbo].[SoftwareProduct]
	WHERE	ModelID = @ModelID
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[SoftwareProductGetAllByPublisherID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[SoftwareProductGetAllByPublisherID]
GO
CREATE PROCEDURE [dbo].[SoftwareProductGetAllByPublisherID]
	@PublisherID		int
AS
	SELECT	SoftwareProductID,
		ProductName,
		ModelID,
		TrackedByID,
		PublisherID,
		Agreement,
		Comments
	FROM	[dbo].[SoftwareProduct]
	WHERE	PublisherID = @PublisherID
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[SoftwareProductGetAll]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[SoftwareProductGetAll]
GO
CREATE PROCEDURE [dbo].[SoftwareProductGetAll]
AS
	SELECT	SoftwareProductID,
		ProductName,
		ModelID,
		TrackedByID,
		PublisherID,
		Agreement,
		Comments
	FROM	[dbo].[SoftwareProduct]
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[SoftwareProductAdd]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[SoftwareProductAdd]
GO
CREATE PROCEDURE [dbo].[SoftwareProductAdd]
	@ProductName		nvarchar(256),
	@ModelID		int,
	@TrackedByID		int,
	@PublisherID		int,
	@Agreement		nvarchar(256),
	@Comments		ntext = NULL
AS
	INSERT INTO  dbo.SoftwareProduct (
		ProductName,
		ModelID,
		TrackedByID,
		PublisherID,
		Agreement,
		Comments
	)
	VALUES (
		@ProductName,
		@ModelID,
		@TrackedByID,
		@PublisherID,
		@Agreement,
		@Comments
	)
	RETURN SCOPE_IDENTITY()
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[SoftwareProductBind]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[SoftwareProductBind]
GO
CREATE PROCEDURE [dbo].[SoftwareProductBind]
	@ProductName		nvarchar(256),
	@ModelID		int,
	@TrackedByID		int,
	@PublisherID		int,
	@Agreement		nvarchar(256),
	@Comments		ntext = NULL
AS
	DECLARE	@ID	int

	SELECT	@ID = SoftwareProductID
	FROM	[dbo].[SoftwareProduct]
	WHERE	ProductName = @ProductName

	IF @ID IS NULL
		EXEC @ID = SoftwareProductAdd @ProductName,
			@ModelID,
			@TrackedByID,
			@PublisherID,
			@Agreement,
			@Comments

	RETURN @ID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[SoftwareProductSchema]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[SoftwareProductSchema]
GO
CREATE PROCEDURE [dbo].[SoftwareProductSchema]
AS
	SELECT
	'IF OBJECT_ID(''tempdb..#SoftwareProduct'') IS NULL' + CAST(0x0A AS CHAR(1)) +
	'	CREATE TABLE #SoftwareProduct (' + CAST(0x0A AS CHAR(1)) +
	'		SoftwareProductID	int NULL,' + CAST(0x0A AS CHAR(1)) +
	'		ProductName		nvarchar(256) COLLATE database_default NOT NULL,' + CAST(0x0A AS CHAR(1)) +
	'		ModelID			int NOT NULL,' + CAST(0x0A AS CHAR(1)) +
	'		TrackedByID		int NOT NULL,' + CAST(0x0A AS CHAR(1)) +
	'		PublisherID		int NOT NULL,' + CAST(0x0A AS CHAR(1)) +
	'		Agreement		nvarchar(256) COLLATE database_default NOT NULL,' + CAST(0x0A AS CHAR(1)) +
	'		Comments		ntext COLLATE database_default NULL' + CAST(0x0A AS CHAR(1)) +
	'	)' + CAST(0x0A AS CHAR(1)) +
	'ELSE' + CAST(0x0A AS CHAR(1)) +
	'	DELETE FROM #SoftwareProduct' + CAST(0x0A AS CHAR(1)) +
	'' AS SQL
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[SoftwareProductTempAdd]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[SoftwareProductTempAdd]
GO
CREATE PROCEDURE dbo.[SoftwareProductTempAdd]
	@SoftwareProductID	int,
	@ProductName		nvarchar(256),
	@ModelID		int,
	@TrackedByID		int,
	@PublisherID		int,
	@Agreement		nvarchar(256),
	@Comments		ntext = NULL
AS
	INSERT INTO #SoftwareProduct (
		SoftwareProductID,
		ProductName,
		ModelID,
		TrackedByID,
		PublisherID,
		Agreement,
		Comments
	)
	VALUES (
		@SoftwareProductID,
		@ProductName,
		@ModelID,
		@TrackedByID,
		@PublisherID,
		@Agreement,
		@Comments
	)
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[SoftwareProductAddBatch]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[SoftwareProductAddBatch]
GO
CREATE PROCEDURE dbo.[SoftwareProductAddBatch]
AS
	DECLARE @count int
	INSERT dbo.SoftwareProduct (
		ProductName,
		ModelID,
		TrackedByID,
		PublisherID,
		Agreement,
		Comments
	)
		SELECT	ProductName,
			ModelID,
			TrackedByID,
			PublisherID,
			Agreement,
			Comments
		FROM #SoftwareProduct
	SET @count = @@ROWCOUNT
	DROP TABLE #SoftwareProduct	-- Drop temporary table
	RETURN @count
GO

/*
Add new SoftwareProduct bound to
	LicenseModel using Name
	SoftwarePublisher using Name
	TargetType using TargetTypeName
	with ProductName, Agreement, Comments
*/

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[SoftwareProductUpdateByID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[SoftwareProductUpdateByID]
GO
CREATE PROCEDURE [dbo].[SoftwareProductUpdateByID]
	@SoftwareProductID	int,
	@ProductName		nvarchar(256),
	@ModelID		int,
	@TrackedByID		int,
	@PublisherID		int,
	@Agreement		nvarchar(256),
	@Comments		ntext = NULL
AS
	DECLARE	@ID	int
	SET @ID = 0

	UPDATE	[dbo].[SoftwareProduct]
	SET	@ID = SoftwareProductID,
		ProductName = @ProductName,
		ModelID = @ModelID,
		TrackedByID = @TrackedByID,
		PublisherID = @PublisherID,
		Agreement = @Agreement,
		Comments = @Comments
	WHERE	SoftwareProductID = @SoftwareProductID
	RETURN @ID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[SoftwareProductUpdateBatchByID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[SoftwareProductUpdateBatchByID]
GO
CREATE PROCEDURE dbo.[SoftwareProductUpdateBatchByID]
AS
	DECLARE @count int

	CREATE INDEX [TempSoftwareProductID]
		ON #SoftwareProduct (SoftwareProductID)

	UPDATE	[dbo].[SoftwareProduct]
	SET	ProductName = t.ProductName,
		ModelID = t.ModelID,
		TrackedByID = t.TrackedByID,
		PublisherID = t.PublisherID,
		Agreement = t.Agreement,
		Comments = t.Comments
	FROM	#SoftwareProduct AS t
	WHERE	SoftwareProduct.SoftwareProductID = t.SoftwareProductID
	SET @count = @@ROWCOUNT
	DROP TABLE #SoftwareProduct	-- Drop the temporary table
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[SoftwareProductUpdateByProductName]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[SoftwareProductUpdateByProductName]
GO
CREATE PROCEDURE [dbo].[SoftwareProductUpdateByProductName]
	@ProductName		nvarchar(256),
	@ModelID		int,
	@TrackedByID		int,
	@PublisherID		int,
	@Agreement		nvarchar(256),
	@Comments		ntext = NULL
AS
	DECLARE	@ID	int
	SET @ID = 0

	UPDATE	[dbo].[SoftwareProduct]
	SET	@ID = SoftwareProductID,
		ModelID = @ModelID,
		TrackedByID = @TrackedByID,
		PublisherID = @PublisherID,
		Agreement = @Agreement,
		Comments = @Comments
	WHERE	ProductName = @ProductName
	RETURN @ID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[SoftwareProductUpdateBatchByProductName]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[SoftwareProductUpdateBatchByProductName]
GO
CREATE PROCEDURE dbo.[SoftwareProductUpdateBatchByProductName]
AS
	DECLARE @count int

	CREATE INDEX [TempSoftwareProductProductName]
		ON #SoftwareProduct (ProductName)

	UPDATE	[dbo].[SoftwareProduct]
	SET	ModelID = t.ModelID,
		TrackedByID = t.TrackedByID,
		PublisherID = t.PublisherID,
		Agreement = t.Agreement,
		Comments = t.Comments
	FROM	#SoftwareProduct AS t
	WHERE	SoftwareProduct.ProductName = t.ProductName
	SET @count = @@ROWCOUNT
	DROP TABLE #SoftwareProduct	-- Drop the temporary table
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[SoftwareProductPutByProductName]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[SoftwareProductPutByProductName]
GO
CREATE PROCEDURE [dbo].[SoftwareProductPutByProductName]
	@ProductName		nvarchar(256),
	@ModelID		int,
	@TrackedByID		int,
	@PublisherID		int,
	@Agreement		nvarchar(256),
	@Comments		ntext = NULL
AS
	DECLARE @ID	int

	SELECT	@ID = SoftwareProductID
	FROM	SoftwareProduct
	WHERE	ProductName = @ProductName

	IF @ID IS NULL
		EXEC @ID = SoftwareProductAdd @ProductName,
			@ModelID,
			@TrackedByID,
			@PublisherID,
			@Agreement,
			@Comments
	ELSE
		EXEC SoftwareProductUpdateByProductName @ProductName,
			@ModelID,
			@TrackedByID,
			@PublisherID,
			@Agreement,
			@Comments

	RETURN @ID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[SoftwareProductPutBatchByProductName]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[SoftwareProductPutBatchByProductName]
GO
CREATE PROCEDURE [dbo].[SoftwareProductPutBatchByProductName]
AS
	DECLARE @count AS int
	SET @count = 0

	CREATE INDEX [TempSoftwareProductProductName]
		ON #SoftwareProduct (ProductName)

	BEGIN TRANSACTION
	UPDATE [dbo].[SoftwareProduct]
		SET	ModelID = t.ModelID,
			TrackedByID = t.TrackedByID,
			PublisherID = t.PublisherID,
			Agreement = t.Agreement,
			Comments = t.Comments
		FROM	#SoftwareProduct AS t
		WHERE	SoftwareProduct.ProductName = t.ProductName
	SET @count = @@ROWCOUNT

	INSERT [dbo].[SoftwareProduct] (
		ProductName,
		ModelID,
		TrackedByID,
		PublisherID,
		Agreement,
		Comments
	)
		SELECT	ProductName,
			ModelID,
			TrackedByID,
			PublisherID,
			Agreement,
			Comments
		FROM	#SoftwareProduct AS t
		WHERE NOT EXISTS(	-- Current record doesn't exist
			SELECT * FROM [dbo].[SoftwareProduct]
			WHERE	SoftwareProduct.ProductName = t.ProductName
		)
	SET @count = @count + @@ROWCOUNT
	DROP TABLE #SoftwareProduct	-- Drop the temporary table
	COMMIT WORK
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[SoftwareProductRemoveBatch]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[SoftwareProductRemoveBatch]
GO

CREATE PROCEDURE [dbo].[SoftwareProductRemoveBatch]
AS

	CREATE INDEX [TempSoftwareProductSoftwareProductRemoveBatch]
		ON #SoftwareProduct (SoftwareProductID)	

	-- Delete records from SoftwareProduct identified by fields of [TempSoftwareProductSoftwareProductRemoveBatch]
	DELETE [dbo].[SoftwareProduct]
	WHERE EXISTS(
			SELECT * FROM #SoftwareProduct AS t
			WHERE	SoftwareProduct.SoftwareProductID = t.SoftwareProductID
		)
	DROP TABLE #SoftwareProduct      -- Drop the temporary table
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[SoftwareProductRemoveByProductName]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[SoftwareProductRemoveByProductName]
GO
CREATE PROCEDURE [dbo].[SoftwareProductRemoveByProductName]
	@ProductName		nvarchar(256)
AS
	-- SoftwareProduct deletes cascade to:
	--	LicenseAllocation by FK_LicenseAllocation_SoftwareProductID
	--	LicensePurchase by FK_LicensePurchase
	--	ProductContainsSoftware by FK_ProductContains_SoftwareProductID
	DELETE	[dbo].[SoftwareProduct]
	WHERE	ProductName = @ProductName
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[SoftwareProductRemoveAll]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[SoftwareProductRemoveAll]
GO
CREATE PROCEDURE [dbo].[SoftwareProductRemoveAll]
	
AS
	DELETE	[dbo].[SoftwareProduct]
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[LicenseAllocationGetAll]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[LicenseAllocationGetAll]
GO
CREATE PROCEDURE [dbo].[LicenseAllocationGetAll]
AS
	SELECT	AllocationID,
		SoftwareProductID,
		OrganizationID,
		UnitsAllocated,
		Expiry
	FROM	[dbo].[LicenseAllocation]
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[LicenseAllocationAdd]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[LicenseAllocationAdd]
GO
CREATE PROCEDURE [dbo].[LicenseAllocationAdd]
	@SoftwareProductID	int,
	@OrganizationID		int,
	@UnitsAllocated		int = NULL,
	@Expiry			datetime = NULL
AS
	INSERT INTO  dbo.LicenseAllocation (
		SoftwareProductID,
		OrganizationID,
		UnitsAllocated,
		Expiry
	)
	VALUES (
		@SoftwareProductID,
		@OrganizationID,
		@UnitsAllocated,
		@Expiry
	)
	RETURN SCOPE_IDENTITY()
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[LicenseAllocationSchema]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[LicenseAllocationSchema]
GO
CREATE PROCEDURE [dbo].[LicenseAllocationSchema]
AS
	SELECT
	'IF OBJECT_ID(''tempdb..#LicenseAllocation'') IS NULL' + CAST(0x0A AS CHAR(1)) +
	'	CREATE TABLE #LicenseAllocation (' + CAST(0x0A AS CHAR(1)) +
	'		AllocationID		int NULL,' + CAST(0x0A AS CHAR(1)) +
	'		SoftwareProductID	int NOT NULL,' + CAST(0x0A AS CHAR(1)) +
	'		OrganizationID		int NOT NULL,' + CAST(0x0A AS CHAR(1)) +
	'		UnitsAllocated		int NULL,' + CAST(0x0A AS CHAR(1)) +
	'		Expiry			datetime NULL' + CAST(0x0A AS CHAR(1)) +
	'	)' + CAST(0x0A AS CHAR(1)) +
	'ELSE' + CAST(0x0A AS CHAR(1)) +
	'	DELETE FROM #LicenseAllocation' + CAST(0x0A AS CHAR(1)) +
	'' AS SQL
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[LicenseAllocationTempAdd]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[LicenseAllocationTempAdd]
GO
CREATE PROCEDURE dbo.[LicenseAllocationTempAdd]
	@AllocationID		int,
	@SoftwareProductID	int,
	@OrganizationID		int,
	@UnitsAllocated		int = NULL,
	@Expiry			datetime = NULL
AS
	INSERT INTO #LicenseAllocation (
		AllocationID,
		SoftwareProductID,
		OrganizationID,
		UnitsAllocated,
		Expiry
	)
	VALUES (
		@AllocationID,
		@SoftwareProductID,
		@OrganizationID,
		@UnitsAllocated,
		@Expiry
	)
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[LicenseAllocationAddBatch]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[LicenseAllocationAddBatch]
GO
CREATE PROCEDURE dbo.[LicenseAllocationAddBatch]
AS
	DECLARE @count int
	INSERT dbo.LicenseAllocation (
		SoftwareProductID,
		OrganizationID,
		UnitsAllocated,
		Expiry
	)
		SELECT	SoftwareProductID,
			OrganizationID,
			UnitsAllocated,
			Expiry
		FROM #LicenseAllocation
	SET @count = @@ROWCOUNT
	DROP TABLE #LicenseAllocation	-- Drop temporary table
	RETURN @count
GO

/*
Add new LicenseAllocation bound to
	Organization using DomainID, RDN
	SoftwareProduct using ProductName with ModelID, TrackedByID, PublisherID, Agreement
	with UnitsAllocated, Expiry
*/

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[LicenseAllocationUpdateByID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[LicenseAllocationUpdateByID]
GO
CREATE PROCEDURE [dbo].[LicenseAllocationUpdateByID]
	@AllocationID		int,
	@SoftwareProductID	int,
	@OrganizationID		int,
	@UnitsAllocated		int = NULL,
	@Expiry			datetime = NULL
AS
	DECLARE	@ID	int
	SET @ID = 0

	UPDATE	[dbo].[LicenseAllocation]
	SET	@ID = AllocationID,
		SoftwareProductID = @SoftwareProductID,
		OrganizationID = @OrganizationID,
		UnitsAllocated = @UnitsAllocated,
		Expiry = @Expiry
	WHERE	AllocationID = @AllocationID
	RETURN @ID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[LicenseAllocationUpdateBatchByID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[LicenseAllocationUpdateBatchByID]
GO
CREATE PROCEDURE dbo.[LicenseAllocationUpdateBatchByID]
AS
	DECLARE @count int

	CREATE INDEX [TempLicenseAllocationID]
		ON #LicenseAllocation (AllocationID)

	UPDATE	[dbo].[LicenseAllocation]
	SET	SoftwareProductID = t.SoftwareProductID,
		OrganizationID = t.OrganizationID,
		UnitsAllocated = t.UnitsAllocated,
		Expiry = t.Expiry
	FROM	#LicenseAllocation AS t
	WHERE	LicenseAllocation.AllocationID = t.AllocationID
	SET @count = @@ROWCOUNT
	DROP TABLE #LicenseAllocation	-- Drop the temporary table
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[LicenseAllocationRemoveBatch]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[LicenseAllocationRemoveBatch]
GO

CREATE PROCEDURE [dbo].[LicenseAllocationRemoveBatch]
AS

	CREATE INDEX [TempLicenseAllocationLicenseAllocationRemoveBatch]
		ON #LicenseAllocation (AllocationID)	

	-- Delete records from LicenseAllocation identified by fields of [TempLicenseAllocationLicenseAllocationRemoveBatch]
	DELETE [dbo].[LicenseAllocation]
	WHERE EXISTS(
			SELECT * FROM #LicenseAllocation AS t
			WHERE	LicenseAllocation.AllocationID = t.AllocationID
		)
	DROP TABLE #LicenseAllocation      -- Drop the temporary table
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[LicenseAllocationRemoveByID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[LicenseAllocationRemoveByID]
GO
CREATE PROCEDURE [dbo].[LicenseAllocationRemoveByID]
	@AllocationID		int
AS
	DELETE	[dbo].[LicenseAllocation]
	WHERE	AllocationID = @AllocationID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[LicenseAllocationRemoveAllBySoftwareProductID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[LicenseAllocationRemoveAllBySoftwareProductID]
GO
CREATE PROCEDURE [dbo].[LicenseAllocationRemoveAllBySoftwareProductID]
	@SoftwareProductID	int
AS
	DELETE	[dbo].[LicenseAllocation]
	WHERE	SoftwareProductID = @SoftwareProductID
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[LicenseAllocationRemoveAll]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[LicenseAllocationRemoveAll]
GO
CREATE PROCEDURE [dbo].[LicenseAllocationRemoveAll]
	
AS
	DELETE	[dbo].[LicenseAllocation]
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[LicensePurchaseGetAllBySoftwareProductID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[LicensePurchaseGetAllBySoftwareProductID]
GO
CREATE PROCEDURE [dbo].[LicensePurchaseGetAllBySoftwareProductID]
	@SoftwareProductID	int
AS
	SELECT	SoftwareProductID,
		ResellerID,
		OrganizationID,
		Purchased,
		Expires,
		Price,
		Quantity,
		OrderNumber
	FROM	[dbo].[LicensePurchase]
	WHERE	SoftwareProductID = @SoftwareProductID
	ORDER BY OrganizationID, ResellerID, Purchased, OrderNumber
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[LicensePurchaseGetAllByResellerID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[LicensePurchaseGetAllByResellerID]
GO
CREATE PROCEDURE [dbo].[LicensePurchaseGetAllByResellerID]
	@ResellerID		int
AS
	SELECT	SoftwareProductID,
		ResellerID,
		OrganizationID,
		Purchased,
		Expires,
		Price,
		Quantity,
		OrderNumber
	FROM	[dbo].[LicensePurchase]
	WHERE	ResellerID = @ResellerID
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[LicensePurchaseGetAll]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[LicensePurchaseGetAll]
GO
CREATE PROCEDURE [dbo].[LicensePurchaseGetAll]
AS
	SELECT	SoftwareProductID,
		ResellerID,
		OrganizationID,
		Purchased,
		Expires,
		Price,
		Quantity,
		OrderNumber
	FROM	[dbo].[LicensePurchase]
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[LicensePurchaseAdd]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[LicensePurchaseAdd]
GO
CREATE PROCEDURE [dbo].[LicensePurchaseAdd]
	@SoftwareProductID	int,
	@ResellerID		int,
	@OrganizationID		int,
	@Purchased		datetime,
	@Expires		datetime = NULL,
	@Price			int = NULL,
	@Quantity		int = 1,
	@OrderNumber		nvarchar(32)
AS
	INSERT INTO  dbo.LicensePurchase (
		SoftwareProductID,
		ResellerID,
		OrganizationID,
		Purchased,
		Expires,
		Price,
		Quantity,
		OrderNumber
	)
	VALUES (
		@SoftwareProductID,
		@ResellerID,
		@OrganizationID,
		@Purchased,
		@Expires,
		@Price,
		@Quantity,
		@OrderNumber
	)
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[LicensePurchaseSchema]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[LicensePurchaseSchema]
GO
CREATE PROCEDURE [dbo].[LicensePurchaseSchema]
AS
	SELECT
	'IF OBJECT_ID(''tempdb..#LicensePurchase'') IS NULL' + CAST(0x0A AS CHAR(1)) +
	'	CREATE TABLE #LicensePurchase (' + CAST(0x0A AS CHAR(1)) +
	'		SoftwareProductID	int NOT NULL,' + CAST(0x0A AS CHAR(1)) +
	'		ResellerID		int NOT NULL,' + CAST(0x0A AS CHAR(1)) +
	'		OrganizationID		int NOT NULL,' + CAST(0x0A AS CHAR(1)) +
	'		Purchased		datetime NOT NULL,' + CAST(0x0A AS CHAR(1)) +
	'		Expires			datetime NULL,' + CAST(0x0A AS CHAR(1)) +
	'		Price			int NULL,' + CAST(0x0A AS CHAR(1)) +
	'		Quantity		int NOT NULL DEFAULT 1,' + CAST(0x0A AS CHAR(1)) +
	'		OrderNumber		nvarchar(32) COLLATE database_default NOT NULL' + CAST(0x0A AS CHAR(1)) +
	'	)' + CAST(0x0A AS CHAR(1)) +
	'ELSE' + CAST(0x0A AS CHAR(1)) +
	'	DELETE FROM #LicensePurchase' + CAST(0x0A AS CHAR(1)) +
	'' AS SQL
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[LicensePurchaseTempAdd]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[LicensePurchaseTempAdd]
GO
CREATE PROCEDURE dbo.[LicensePurchaseTempAdd]
	@SoftwareProductID	int,
	@ResellerID		int,
	@OrganizationID		int,
	@Purchased		datetime,
	@Expires		datetime = NULL,
	@Price			int = NULL,
	@Quantity		int = 1,
	@OrderNumber		nvarchar(32)
AS
	INSERT INTO #LicensePurchase (
		SoftwareProductID,
		ResellerID,
		OrganizationID,
		Purchased,
		Expires,
		Price,
		Quantity,
		OrderNumber
	)
	VALUES (
		@SoftwareProductID,
		@ResellerID,
		@OrganizationID,
		@Purchased,
		@Expires,
		@Price,
		@Quantity,
		@OrderNumber
	)
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[LicensePurchaseAddBatch]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[LicensePurchaseAddBatch]
GO
CREATE PROCEDURE dbo.[LicensePurchaseAddBatch]
AS
	DECLARE @count int
	INSERT dbo.LicensePurchase (
		SoftwareProductID,
		ResellerID,
		OrganizationID,
		Purchased,
		Expires,
		Price,
		Quantity,
		OrderNumber
	)
		SELECT	SoftwareProductID,
			ResellerID,
			OrganizationID,
			Purchased,
			Expires,
			Price,
			Quantity,
			OrderNumber
		FROM #LicensePurchase
	SET @count = @@ROWCOUNT
	DROP TABLE #LicensePurchase	-- Drop temporary table
	RETURN @count
GO

/*
Add new LicensePurchase bound to
	SoftwareReseller using Name
	Organization using DomainID, RDN
	SoftwareProduct using ProductName with ModelID, TrackedByID, PublisherID, Agreement
	with Purchased, Expires, Price, Quantity, OrderNumber
*/

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[LicensePurchaseUpdateBySoftwareProductIDOrganizationIDResellerIDPurchasedOrderNumber]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[LicensePurchaseUpdateBySoftwareProductIDOrganizationIDResellerIDPurchasedOrderNumber]
GO
CREATE PROCEDURE [dbo].[LicensePurchaseUpdateBySoftwareProductIDOrganizationIDResellerIDPurchasedOrderNumber]
	@SoftwareProductID	int,
	@OrganizationID		int,
	@ResellerID		int,
	@Purchased		datetime,
	@OrderNumber		nvarchar(32),
	@Expires		datetime = NULL,
	@Price			int = NULL,
	@Quantity		int = 1
AS
	UPDATE	[dbo].[LicensePurchase]
	SET	Expires = @Expires,
		Price = @Price,
		Quantity = @Quantity
	WHERE	SoftwareProductID = @SoftwareProductID
	  AND	OrganizationID = @OrganizationID
	  AND	ResellerID = @ResellerID
	  AND	Purchased = @Purchased
	  AND	OrderNumber = @OrderNumber
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[LicensePurchaseUpdateBatchBySoftwareProductIDOrganizationIDResellerIDPurchasedOrderNumber]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[LicensePurchaseUpdateBatchBySoftwareProductIDOrganizationIDResellerIDPurchasedOrderNumber]
GO
CREATE PROCEDURE dbo.[LicensePurchaseUpdateBatchBySoftwareProductIDOrganizationIDResellerIDPurchasedOrderNumber]
AS
	DECLARE @count int

	CREATE INDEX [TempLicensePurchaseSoftwareProductIDOrganizationIDResellerIDPurchasedOrderNumber]
		ON #LicensePurchase (SoftwareProductID, OrganizationID, ResellerID, Purchased, OrderNumber)

	UPDATE	[dbo].[LicensePurchase]
	SET	Expires = t.Expires,
		Price = t.Price,
		Quantity = t.Quantity
	FROM	#LicensePurchase AS t
	WHERE	LicensePurchase.SoftwareProductID = t.SoftwareProductID
	  AND	LicensePurchase.OrganizationID = t.OrganizationID
	  AND	LicensePurchase.ResellerID = t.ResellerID
	  AND	LicensePurchase.Purchased = t.Purchased
	  AND	LicensePurchase.OrderNumber = t.OrderNumber
	SET @count = @@ROWCOUNT
	DROP TABLE #LicensePurchase	-- Drop the temporary table
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[LicensePurchasePutBySoftwareProductIDOrganizationIDResellerIDPurchasedOrderNumber]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[LicensePurchasePutBySoftwareProductIDOrganizationIDResellerIDPurchasedOrderNumber]
GO
CREATE PROCEDURE [dbo].[LicensePurchasePutBySoftwareProductIDOrganizationIDResellerIDPurchasedOrderNumber]
	@SoftwareProductID	int,
	@OrganizationID		int,
	@ResellerID		int,
	@Purchased		datetime,
	@OrderNumber		nvarchar(32),
	@Expires		datetime = NULL,
	@Price			int = NULL,
	@Quantity		int = 1
AS
	IF NOT EXISTS(
		SELECT	1
		FROM	dbo.LicensePurchase
		WHERE	SoftwareProductID = @SoftwareProductID
		  AND	OrganizationID = @OrganizationID
		  AND	ResellerID = @ResellerID
		  AND	Purchased = @Purchased
		  AND	OrderNumber = @OrderNumber
	)
		EXEC LicensePurchaseAdd @SoftwareProductID,
			@ResellerID,
			@OrganizationID,
			@Purchased,
			@Expires,
			@Price,
			@Quantity,
			@OrderNumber
	ELSE
		EXEC LicensePurchaseUpdateBySoftwareProductIDOrganizationIDResellerIDPurchasedOrderNumber @SoftwareProductID,
			@OrganizationID,
			@ResellerID,
			@Purchased,
			@OrderNumber,
			@Expires,
			@Price,
			@Quantity
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[LicensePurchasePutBatchBySoftwareProductIDOrganizationIDResellerIDPurchasedOrderNumber]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[LicensePurchasePutBatchBySoftwareProductIDOrganizationIDResellerIDPurchasedOrderNumber]
GO
CREATE PROCEDURE [dbo].[LicensePurchasePutBatchBySoftwareProductIDOrganizationIDResellerIDPurchasedOrderNumber]
AS
	DECLARE @count AS int
	SET @count = 0

	CREATE INDEX [TempLicensePurchaseSoftwareProductIDOrganizationIDResellerIDPurchasedOrderNumber]
		ON #LicensePurchase (SoftwareProductID, OrganizationID, ResellerID, Purchased, OrderNumber)

	BEGIN TRANSACTION
	UPDATE [dbo].[LicensePurchase]
		SET	Expires = t.Expires,
			Price = t.Price,
			Quantity = t.Quantity
		FROM	#LicensePurchase AS t
		WHERE	LicensePurchase.SoftwareProductID = t.SoftwareProductID
		  AND	LicensePurchase.OrganizationID = t.OrganizationID
		  AND	LicensePurchase.ResellerID = t.ResellerID
		  AND	LicensePurchase.Purchased = t.Purchased
		  AND	LicensePurchase.OrderNumber = t.OrderNumber
	SET @count = @@ROWCOUNT

	INSERT [dbo].[LicensePurchase] (
		SoftwareProductID,
		ResellerID,
		OrganizationID,
		Purchased,
		Expires,
		Price,
		Quantity,
		OrderNumber
	)
		SELECT	SoftwareProductID,
			ResellerID,
			OrganizationID,
			Purchased,
			Expires,
			Price,
			Quantity,
			OrderNumber
		FROM	#LicensePurchase AS t
		WHERE NOT EXISTS(	-- Current record doesn't exist
			SELECT * FROM [dbo].[LicensePurchase]
			WHERE	LicensePurchase.SoftwareProductID = t.SoftwareProductID
			  AND	LicensePurchase.OrganizationID = t.OrganizationID
			  AND	LicensePurchase.ResellerID = t.ResellerID
			  AND	LicensePurchase.Purchased = t.Purchased
			  AND	LicensePurchase.OrderNumber = t.OrderNumber
		)
	SET @count = @count + @@ROWCOUNT
	DROP TABLE #LicensePurchase	-- Drop the temporary table
	COMMIT WORK
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[LicensePurchaseRemoveBatch]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[LicensePurchaseRemoveBatch]
GO

CREATE PROCEDURE [dbo].[LicensePurchaseRemoveBatch]
AS

	CREATE INDEX [TempLicensePurchaseLicensePurchaseRemoveBatch]
		ON #LicensePurchase (SoftwareProductID, OrganizationID, ResellerID, Purchased, OrderNumber)	

	-- Delete records from LicensePurchase identified by fields of [TempLicensePurchaseLicensePurchaseRemoveBatch]
	DELETE [dbo].[LicensePurchase]
	WHERE EXISTS(
			SELECT * FROM #LicensePurchase AS t
			WHERE	LicensePurchase.SoftwareProductID = t.SoftwareProductID
			  AND	LicensePurchase.OrganizationID = t.OrganizationID
			  AND	LicensePurchase.ResellerID = t.ResellerID
			  AND	LicensePurchase.Purchased = t.Purchased
			  AND	LicensePurchase.OrderNumber = t.OrderNumber
		)
	DROP TABLE #LicensePurchase      -- Drop the temporary table
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[LicensePurchaseRemoveBySoftwareProductIDOrganizationIDResellerIDPurchasedOrderNumber]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[LicensePurchaseRemoveBySoftwareProductIDOrganizationIDResellerIDPurchasedOrderNumber]
GO
CREATE PROCEDURE [dbo].[LicensePurchaseRemoveBySoftwareProductIDOrganizationIDResellerIDPurchasedOrderNumber]
	@SoftwareProductID	int,
	@OrganizationID		int,
	@ResellerID		int,
	@Purchased		datetime,
	@OrderNumber		nvarchar(32)
AS
	DELETE	[dbo].[LicensePurchase]
	WHERE	SoftwareProductID = @SoftwareProductID
	  AND	OrganizationID = @OrganizationID
	  AND	ResellerID = @ResellerID
	  AND	Purchased = @Purchased
	  AND	OrderNumber = @OrderNumber
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[LicensePurchaseRemoveAllBySoftwareProductID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[LicensePurchaseRemoveAllBySoftwareProductID]
GO
CREATE PROCEDURE [dbo].[LicensePurchaseRemoveAllBySoftwareProductID]
	@SoftwareProductID	int
AS
	DELETE	[dbo].[LicensePurchase]
	WHERE	SoftwareProductID = @SoftwareProductID
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[LicensePurchaseRemoveAll]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[LicensePurchaseRemoveAll]
GO
CREATE PROCEDURE [dbo].[LicensePurchaseRemoveAll]
	
AS
	DELETE	[dbo].[LicensePurchase]
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ProductContainsSoftwareGetBySoftwareVersionIDSoftwareProductID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ProductContainsSoftwareGetBySoftwareVersionIDSoftwareProductID]
GO
CREATE PROCEDURE [dbo].[ProductContainsSoftwareGetBySoftwareVersionIDSoftwareProductID]
	@SoftwareVersionID	int,
	@SoftwareProductID	int
AS
	SELECT	SoftwareProductID,
		SoftwareVersionID
	FROM	[dbo].[ProductContainsSoftware]
	WHERE	SoftwareVersionID = @SoftwareVersionID
	  AND	SoftwareProductID = @SoftwareProductID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ProductContainsSoftwareGetAllBySoftwareProductID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ProductContainsSoftwareGetAllBySoftwareProductID]
GO
CREATE PROCEDURE [dbo].[ProductContainsSoftwareGetAllBySoftwareProductID]
	@SoftwareProductID	int
AS
	SELECT	SoftwareProductID,
		SoftwareVersionID
	FROM	[dbo].[ProductContainsSoftware]
	WHERE	SoftwareProductID = @SoftwareProductID
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ProductContainsSoftwareGetAll]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ProductContainsSoftwareGetAll]
GO
CREATE PROCEDURE [dbo].[ProductContainsSoftwareGetAll]
AS
	SELECT	SoftwareProductID,
		SoftwareVersionID
	FROM	[dbo].[ProductContainsSoftware]
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ProductContainsSoftwareAdd]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ProductContainsSoftwareAdd]
GO
CREATE PROCEDURE [dbo].[ProductContainsSoftwareAdd]
	@SoftwareProductID	int,
	@SoftwareVersionID	int
AS
	INSERT INTO  dbo.ProductContainsSoftware (
		SoftwareProductID,
		SoftwareVersionID
	)
	VALUES (
		@SoftwareProductID,
		@SoftwareVersionID
	)
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ProductContainsSoftwareSchema]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ProductContainsSoftwareSchema]
GO
CREATE PROCEDURE [dbo].[ProductContainsSoftwareSchema]
AS
	SELECT
	'IF OBJECT_ID(''tempdb..#ProductContainsSoftware'') IS NULL' + CAST(0x0A AS CHAR(1)) +
	'	CREATE TABLE #ProductContainsSoftware (' + CAST(0x0A AS CHAR(1)) +
	'		SoftwareProductID	int NOT NULL,' + CAST(0x0A AS CHAR(1)) +
	'		SoftwareVersionID	int NOT NULL' + CAST(0x0A AS CHAR(1)) +
	'	)' + CAST(0x0A AS CHAR(1)) +
	'ELSE' + CAST(0x0A AS CHAR(1)) +
	'	DELETE FROM #ProductContainsSoftware' + CAST(0x0A AS CHAR(1)) +
	'' AS SQL
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ProductContainsSoftwareTempAdd]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ProductContainsSoftwareTempAdd]
GO
CREATE PROCEDURE dbo.[ProductContainsSoftwareTempAdd]
	@SoftwareProductID	int,
	@SoftwareVersionID	int
AS
	INSERT INTO #ProductContainsSoftware (
		SoftwareProductID,
		SoftwareVersionID
	)
	VALUES (
		@SoftwareProductID,
		@SoftwareVersionID
	)
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ProductContainsSoftwareAddBatch]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ProductContainsSoftwareAddBatch]
GO
CREATE PROCEDURE dbo.[ProductContainsSoftwareAddBatch]
AS
	DECLARE @count int
	INSERT dbo.ProductContainsSoftware (
		SoftwareProductID,
		SoftwareVersionID
	)
		SELECT	SoftwareProductID,
			SoftwareVersionID
		FROM #ProductContainsSoftware
	SET @count = @@ROWCOUNT
	DROP TABLE #ProductContainsSoftware	-- Drop temporary table
	RETURN @count
GO

/*
Add new ProductContainsSoftware bound to
	SoftwareProduct using ProductName with ModelID, TrackedByID, PublisherID, Agreement
	SoftwareVersion using SoftwareName, Version
	with 
*/

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ProductContainsSoftwarePutBySoftwareVersionIDSoftwareProductID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ProductContainsSoftwarePutBySoftwareVersionIDSoftwareProductID]
GO
CREATE PROCEDURE [dbo].[ProductContainsSoftwarePutBySoftwareVersionIDSoftwareProductID]
	@SoftwareVersionID	int,
	@SoftwareProductID	int
AS
	IF NOT EXISTS(
		SELECT	1
		FROM	dbo.ProductContainsSoftware
		WHERE	SoftwareVersionID = @SoftwareVersionID
		  AND	SoftwareProductID = @SoftwareProductID
	)
		EXEC ProductContainsSoftwareAdd @SoftwareProductID,
			@SoftwareVersionID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ProductContainsSoftwarePutBatchBySoftwareVersionIDSoftwareProductID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ProductContainsSoftwarePutBatchBySoftwareVersionIDSoftwareProductID]
GO
CREATE PROCEDURE [dbo].[ProductContainsSoftwarePutBatchBySoftwareVersionIDSoftwareProductID]
AS
	DECLARE @count AS int
	SET @count = 0

	CREATE INDEX [TempProductContainsSoftwareSoftwareVersionIDSoftwareProductID]
		ON #ProductContainsSoftware (SoftwareVersionID, SoftwareProductID)

	BEGIN TRANSACTION

	INSERT [dbo].[ProductContainsSoftware] (
		SoftwareProductID,
		SoftwareVersionID
	)
		SELECT	SoftwareProductID,
			SoftwareVersionID
		FROM	#ProductContainsSoftware AS t
		WHERE NOT EXISTS(	-- Current record doesn't exist
			SELECT * FROM [dbo].[ProductContainsSoftware]
			WHERE	ProductContainsSoftware.SoftwareVersionID = t.SoftwareVersionID
			  AND	ProductContainsSoftware.SoftwareProductID = t.SoftwareProductID
		)
	SET @count = @count + @@ROWCOUNT
	DROP TABLE #ProductContainsSoftware	-- Drop the temporary table
	COMMIT WORK
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ProductContainsSoftwareRemoveBatch]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ProductContainsSoftwareRemoveBatch]
GO

CREATE PROCEDURE [dbo].[ProductContainsSoftwareRemoveBatch]
AS

	CREATE INDEX [TempProductContainsSoftwareProductContainsSoftwareRemoveBatch]
		ON #ProductContainsSoftware (SoftwareVersionID, SoftwareProductID)	

	-- Delete records from ProductContainsSoftware identified by fields of [TempProductContainsSoftwareProductContainsSoftwareRemoveBatch]
	DELETE [dbo].[ProductContainsSoftware]
	WHERE EXISTS(
			SELECT * FROM #ProductContainsSoftware AS t
			WHERE	ProductContainsSoftware.SoftwareVersionID = t.SoftwareVersionID
			  AND	ProductContainsSoftware.SoftwareProductID = t.SoftwareProductID
		)
	DROP TABLE #ProductContainsSoftware      -- Drop the temporary table
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ProductContainsSoftwareRemoveBySoftwareVersionIDSoftwareProductID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ProductContainsSoftwareRemoveBySoftwareVersionIDSoftwareProductID]
GO
CREATE PROCEDURE [dbo].[ProductContainsSoftwareRemoveBySoftwareVersionIDSoftwareProductID]
	@SoftwareVersionID	int,
	@SoftwareProductID	int
AS
	DELETE	[dbo].[ProductContainsSoftware]
	WHERE	SoftwareVersionID = @SoftwareVersionID
	  AND	SoftwareProductID = @SoftwareProductID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ProductContainsSoftwareRemoveAllBySoftwareProductID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ProductContainsSoftwareRemoveAllBySoftwareProductID]
GO
CREATE PROCEDURE [dbo].[ProductContainsSoftwareRemoveAllBySoftwareProductID]
	@SoftwareProductID	int
AS
	DELETE	[dbo].[ProductContainsSoftware]
	WHERE	SoftwareProductID = @SoftwareProductID
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ProductContainsSoftwareRemoveAll]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ProductContainsSoftwareRemoveAll]
GO
CREATE PROCEDURE [dbo].[ProductContainsSoftwareRemoveAll]
	
AS
	DELETE	[dbo].[ProductContainsSoftware]
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ProductContainsSoftwareReplaceSubsetBySoftwareProductID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ProductContainsSoftwareReplaceSubsetBySoftwareProductID]
GO
-- Replace the record subset selected by (@SoftwareProductID)
-- using unique identifier (SoftwareVersionID, SoftwareProductID)
CREATE PROCEDURE [dbo].[ProductContainsSoftwareReplaceSubsetBySoftwareProductID]
	@SoftwareProductID	int
AS
	DECLARE @count AS int
	SET @count = 0

	CREATE INDEX [TempProductContainsSoftwareBySoftwareProductID]
		ON #ProductContainsSoftware (SoftwareVersionID, SoftwareProductID)

	BEGIN TRANSACTION
	DELETE [ProductContainsSoftware]
		WHERE	SoftwareProductID = @SoftwareProductID
		AND NOT EXISTS(		-- Replacement record doesn't exist
			SELECT * FROM #ProductContainsSoftware AS t
			WHERE	ProductContainsSoftware.SoftwareVersionID = t.SoftwareVersionID
			  AND	ProductContainsSoftware.SoftwareProductID = t.SoftwareProductID
		)

	INSERT [ProductContainsSoftware] (
		SoftwareProductID,
		SoftwareVersionID
	)
		SELECT	SoftwareProductID,
			SoftwareVersionID
		FROM	#ProductContainsSoftware AS t
		WHERE NOT EXISTS(	-- Current record doesn't exist
			SELECT * FROM [ProductContainsSoftware]
			WHERE	ProductContainsSoftware.SoftwareVersionID = t.SoftwareVersionID
			  AND	ProductContainsSoftware.SoftwareProductID = t.SoftwareProductID
		)
	SET @count = @count + @@ROWCOUNT
	DROP TABLE #ProductContainsSoftware	-- Drop the temporary table
	COMMIT WORK
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[PolicyGetByGUID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[PolicyGetByGUID]
GO
CREATE PROCEDURE [dbo].[PolicyGetByGUID]
	@GUID			binary(16)
AS
	SELECT	GUID,
		DomainID,
		DisplayName,
		AccessGroupID,
		EnabledForUsers,
		EnabledForComputers
	FROM	[dbo].[Policy]
	WHERE	GUID = @GUID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[PolicyGetAllByDomainIDDisplayName]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[PolicyGetAllByDomainIDDisplayName]
GO
CREATE PROCEDURE [dbo].[PolicyGetAllByDomainIDDisplayName]
	@DomainID		int = NULL,
	@DisplayName		nvarchar(512) = NULL
AS
	SELECT	GUID,
		DomainID,
		DisplayName,
		AccessGroupID,
		EnabledForUsers,
		EnabledForComputers
	FROM	[dbo].[Policy]
	WHERE	(DomainID = @DomainID OR (DomainID IS NULL AND @DomainID IS NULL))
	  AND	(DisplayName = @DisplayName OR (DisplayName IS NULL AND @DisplayName IS NULL))
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[PolicyGetAllByDomainID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[PolicyGetAllByDomainID]
GO
CREATE PROCEDURE [dbo].[PolicyGetAllByDomainID]
	@DomainID		int = NULL
AS
	SELECT	GUID,
		DomainID,
		DisplayName,
		AccessGroupID,
		EnabledForUsers,
		EnabledForComputers
	FROM	[dbo].[Policy]
	WHERE	(DomainID = @DomainID OR (DomainID IS NULL AND @DomainID IS NULL))
	ORDER BY DisplayName
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[PolicyGetAll]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[PolicyGetAll]
GO
CREATE PROCEDURE [dbo].[PolicyGetAll]
AS
	SELECT	GUID,
		DomainID,
		DisplayName,
		AccessGroupID,
		EnabledForUsers,
		EnabledForComputers
	FROM	[dbo].[Policy]
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[PolicyAdd]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[PolicyAdd]
GO
CREATE PROCEDURE [dbo].[PolicyAdd]
	@GUID			binary(16),
	@DomainID		int = NULL,
	@DisplayName		nvarchar(512) = NULL,
	@AccessGroupID		int = NULL,
	@EnabledForUsers	bit = 1,
	@EnabledForComputers	bit = 1
AS
	INSERT INTO  dbo.Policy (
		GUID,
		DomainID,
		DisplayName,
		AccessGroupID,
		EnabledForUsers,
		EnabledForComputers
	)
	VALUES (
		@GUID,
		@DomainID,
		@DisplayName,
		@AccessGroupID,
		@EnabledForUsers,
		@EnabledForComputers
	)
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[PolicySchema]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[PolicySchema]
GO
CREATE PROCEDURE [dbo].[PolicySchema]
AS
	SELECT
	'IF OBJECT_ID(''tempdb..#Policy'') IS NULL' + CAST(0x0A AS CHAR(1)) +
	'	CREATE TABLE #Policy (' + CAST(0x0A AS CHAR(1)) +
	'		GUID			binary(16) NOT NULL,' + CAST(0x0A AS CHAR(1)) +
	'		DomainID		int NULL,' + CAST(0x0A AS CHAR(1)) +
	'		DisplayName		nvarchar(512) COLLATE database_default NULL,' + CAST(0x0A AS CHAR(1)) +
	'		AccessGroupID		int NULL,' + CAST(0x0A AS CHAR(1)) +
	'		EnabledForUsers		bit NOT NULL DEFAULT 1,' + CAST(0x0A AS CHAR(1)) +
	'		EnabledForComputers	bit NOT NULL DEFAULT 1' + CAST(0x0A AS CHAR(1)) +
	'	)' + CAST(0x0A AS CHAR(1)) +
	'ELSE' + CAST(0x0A AS CHAR(1)) +
	'	DELETE FROM #Policy' + CAST(0x0A AS CHAR(1)) +
	'' AS SQL
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[PolicyTempAdd]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[PolicyTempAdd]
GO
CREATE PROCEDURE dbo.[PolicyTempAdd]
	@GUID			binary(16),
	@DomainID		int = NULL,
	@DisplayName		nvarchar(512) = NULL,
	@AccessGroupID		int = NULL,
	@EnabledForUsers	bit = 1,
	@EnabledForComputers	bit = 1
AS
	INSERT INTO #Policy (
		GUID,
		DomainID,
		DisplayName,
		AccessGroupID,
		EnabledForUsers,
		EnabledForComputers
	)
	VALUES (
		@GUID,
		@DomainID,
		@DisplayName,
		@AccessGroupID,
		@EnabledForUsers,
		@EnabledForComputers
	)
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[PolicyAddBatch]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[PolicyAddBatch]
GO
CREATE PROCEDURE dbo.[PolicyAddBatch]
AS
	DECLARE @count int
	INSERT dbo.Policy (
		GUID,
		DomainID,
		DisplayName,
		AccessGroupID,
		EnabledForUsers,
		EnabledForComputers
	)
		SELECT	GUID,
			DomainID,
			DisplayName,
			AccessGroupID,
			EnabledForUsers,
			EnabledForComputers
		FROM #Policy
	SET @count = @@ROWCOUNT
	DROP TABLE #Policy	-- Drop temporary table
	RETURN @count
GO

/*
Add new Policy bound to
	Group using GUID with GroupOUID
	with GUID, DomainID, DisplayName, EnabledForUsers, EnabledForComputers
*/

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[PolicyUpdateByGUID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[PolicyUpdateByGUID]
GO
CREATE PROCEDURE [dbo].[PolicyUpdateByGUID]
	@GUID			binary(16),
	@DomainID		int = NULL,
	@DisplayName		nvarchar(512) = NULL,
	@AccessGroupID		int = NULL,
	@EnabledForUsers	bit = 1,
	@EnabledForComputers	bit = 1
AS
	UPDATE	[dbo].[Policy]
	SET	DomainID = @DomainID,
		DisplayName = @DisplayName,
		AccessGroupID = @AccessGroupID,
		EnabledForUsers = @EnabledForUsers,
		EnabledForComputers = @EnabledForComputers
	WHERE	GUID = @GUID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[PolicyUpdateBatchByGUID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[PolicyUpdateBatchByGUID]
GO
CREATE PROCEDURE dbo.[PolicyUpdateBatchByGUID]
AS
	DECLARE @count int

	CREATE INDEX [TempPolicyGUID]
		ON #Policy (GUID)

	UPDATE	[dbo].[Policy]
	SET	DomainID = t.DomainID,
		DisplayName = t.DisplayName,
		AccessGroupID = t.AccessGroupID,
		EnabledForUsers = t.EnabledForUsers,
		EnabledForComputers = t.EnabledForComputers
	FROM	#Policy AS t
	WHERE	Policy.GUID = t.GUID
	SET @count = @@ROWCOUNT
	DROP TABLE #Policy	-- Drop the temporary table
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[PolicyPutByGUID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[PolicyPutByGUID]
GO
CREATE PROCEDURE [dbo].[PolicyPutByGUID]
	@GUID			binary(16),
	@DomainID		int = NULL,
	@DisplayName		nvarchar(512) = NULL,
	@AccessGroupID		int = NULL,
	@EnabledForUsers	bit = 1,
	@EnabledForComputers	bit = 1
AS
	IF NOT EXISTS(
		SELECT	1
		FROM	dbo.Policy
		WHERE	GUID = @GUID
	)
		EXEC PolicyAdd @GUID,
			@DomainID,
			@DisplayName,
			@AccessGroupID,
			@EnabledForUsers,
			@EnabledForComputers
	ELSE
		EXEC PolicyUpdateByGUID @GUID,
			@DomainID,
			@DisplayName,
			@AccessGroupID,
			@EnabledForUsers,
			@EnabledForComputers
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[PolicyPutBatchByGUID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[PolicyPutBatchByGUID]
GO
CREATE PROCEDURE [dbo].[PolicyPutBatchByGUID]
AS
	DECLARE @count AS int
	SET @count = 0

	CREATE INDEX [TempPolicyGUID]
		ON #Policy (GUID)

	BEGIN TRANSACTION
	UPDATE [dbo].[Policy]
		SET	DomainID = t.DomainID,
			DisplayName = t.DisplayName,
			AccessGroupID = t.AccessGroupID,
			EnabledForUsers = t.EnabledForUsers,
			EnabledForComputers = t.EnabledForComputers
		FROM	#Policy AS t
		WHERE	Policy.GUID = t.GUID
	SET @count = @@ROWCOUNT

	INSERT [dbo].[Policy] (
		GUID,
		DomainID,
		DisplayName,
		AccessGroupID,
		EnabledForUsers,
		EnabledForComputers
	)
		SELECT	GUID,
			DomainID,
			DisplayName,
			AccessGroupID,
			EnabledForUsers,
			EnabledForComputers
		FROM	#Policy AS t
		WHERE NOT EXISTS(	-- Current record doesn't exist
			SELECT * FROM [dbo].[Policy]
			WHERE	Policy.GUID = t.GUID
		)
	SET @count = @count + @@ROWCOUNT
	DROP TABLE #Policy	-- Drop the temporary table
	COMMIT WORK
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[PolicyRemoveBatch]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[PolicyRemoveBatch]
GO

CREATE PROCEDURE [dbo].[PolicyRemoveBatch]
AS

	CREATE INDEX [TempPolicyPolicyRemoveBatch]
		ON #Policy (GUID)	

	-- Delete records from Policy identified by fields of [TempPolicyPolicyRemoveBatch]
	DELETE [dbo].[Policy]
	WHERE EXISTS(
			SELECT * FROM #Policy AS t
			WHERE	Policy.GUID = t.GUID
		)
	DROP TABLE #Policy      -- Drop the temporary table
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[PolicyRemoveByGUID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[PolicyRemoveByGUID]
GO
CREATE PROCEDURE [dbo].[PolicyRemoveByGUID]
	@GUID			binary(16)
AS
	-- Policy deletes cascade to:
	--	PackageAllocation by FK_Allocation_Policy
	--	PolicyApplies by FK_PolicyApplies_Policy
	--	PackageApplies by FK_PackageApplies_Policy
	--	InstallationPostponement by FK_InstallationPostponement_Policy
	DELETE	[dbo].[Policy]
	WHERE	GUID = @GUID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[PolicyRemoveAllByDomainID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[PolicyRemoveAllByDomainID]
GO
CREATE PROCEDURE [dbo].[PolicyRemoveAllByDomainID]
	@DomainID		int = NULL
AS
	DELETE	[dbo].[Policy]
	WHERE	(DomainID = @DomainID OR (DomainID IS NULL AND @DomainID IS NULL))
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[PolicyRemoveAll]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[PolicyRemoveAll]
GO
CREATE PROCEDURE [dbo].[PolicyRemoveAll]
	
AS
	DELETE	[dbo].[Policy]
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[PolicyReplaceSubsetByDomainID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[PolicyReplaceSubsetByDomainID]
GO
-- Replace the record subset selected by (@DomainID)
-- using unique identifier (GUID)
-- updating fields (DisplayName, AccessGroupID, EnabledForUsers, EnabledForComputers)
CREATE PROCEDURE [dbo].[PolicyReplaceSubsetByDomainID]
	@DomainID		int = NULL
AS
	DECLARE @count AS int
	SET @count = 0

	CREATE INDEX [TempPolicyByDomainID]
		ON #Policy (GUID)

	BEGIN TRANSACTION
	DELETE [Policy]
		WHERE	(DomainID = @DomainID OR (DomainID IS NULL AND @DomainID IS NULL))
		AND NOT EXISTS(		-- Replacement record doesn't exist
			SELECT * FROM #Policy AS t
			WHERE	Policy.GUID = t.GUID
		)

	UPDATE [dbo].[Policy]
		SET	DisplayName = t.DisplayName,
			AccessGroupID = t.AccessGroupID,
			EnabledForUsers = t.EnabledForUsers,
			EnabledForComputers = t.EnabledForComputers
		FROM	#Policy AS t
		WHERE	Policy.GUID = t.GUID
	SET @count = @@ROWCOUNT

	INSERT [Policy] (
		GUID,
		DomainID,
		DisplayName,
		AccessGroupID,
		EnabledForUsers,
		EnabledForComputers
	)
		SELECT	GUID,
			DomainID,
			DisplayName,
			AccessGroupID,
			EnabledForUsers,
			EnabledForComputers
		FROM	#Policy AS t
		WHERE NOT EXISTS(	-- Current record doesn't exist
			SELECT * FROM [Policy]
			WHERE	Policy.GUID = t.GUID
		)
	SET @count = @count + @@ROWCOUNT
	DROP TABLE #Policy	-- Drop the temporary table
	COMMIT WORK
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[AllocationDetailsGetByID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[AllocationDetailsGetByID]
GO
CREATE PROCEDURE [dbo].[AllocationDetailsGetByID]
	@AllocationDetailsID	int
AS
	SELECT	AllocationDetailsID,
		Action,
		EffectiveFrom,
		EffectiveFromIsLocal,
		EffectiveUntil,
		Wake,
		PostponeNoLaterThan,
		PostponeNoLaterThanIsLocal,
		PostponePeriod,
		PostponeLatest,
		PostponeOKForLowBandwidth,
		PostponeOKForAnyReason,
		Exclusive,
		Removable
	FROM	[dbo].[AllocationDetails]
	WHERE	AllocationDetailsID = @AllocationDetailsID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[AllocationDetailsGetByAll]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[AllocationDetailsGetByAll]
GO
CREATE PROCEDURE [dbo].[AllocationDetailsGetByAll]
	@Action			varchar(16) = NULL,
	@EffectiveFrom		datetime = NULL,
	@EffectiveFromIsLocal	bit = 1,
	@EffectiveUntil		datetime = NULL,
	@Wake			bit = 0,
	@PostponeNoLaterThan	datetime = NULL,
	@PostponeNoLaterThanIsLocal bit = 0,
	@PostponePeriod		int = NULL,
	@PostponeLatest		bit = 1,
	@PostponeOKForLowBandwidth bit = 1,
	@PostponeOKForAnyReason	bit = 1,
	@Exclusive		bit = 0,
	@Removable		bit = 0
AS
	SELECT	AllocationDetailsID,
		Action,
		EffectiveFrom,
		EffectiveFromIsLocal,
		EffectiveUntil,
		Wake,
		PostponeNoLaterThan,
		PostponeNoLaterThanIsLocal,
		PostponePeriod,
		PostponeLatest,
		PostponeOKForLowBandwidth,
		PostponeOKForAnyReason,
		Exclusive,
		Removable
	FROM	[dbo].[AllocationDetails]
	WHERE	(Action = @Action OR (Action IS NULL AND @Action IS NULL))
	  AND	(EffectiveFrom = @EffectiveFrom OR (EffectiveFrom IS NULL AND @EffectiveFrom IS NULL))
	  AND	(EffectiveFromIsLocal = @EffectiveFromIsLocal OR (EffectiveFromIsLocal IS NULL AND @EffectiveFromIsLocal IS NULL))
	  AND	(EffectiveUntil = @EffectiveUntil OR (EffectiveUntil IS NULL AND @EffectiveUntil IS NULL))
	  AND	(Wake = @Wake OR (Wake IS NULL AND @Wake IS NULL))
	  AND	(PostponeNoLaterThan = @PostponeNoLaterThan OR (PostponeNoLaterThan IS NULL AND @PostponeNoLaterThan IS NULL))
	  AND	PostponeNoLaterThanIsLocal = @PostponeNoLaterThanIsLocal
	  AND	(PostponePeriod = @PostponePeriod OR (PostponePeriod IS NULL AND @PostponePeriod IS NULL))
	  AND	PostponeLatest = @PostponeLatest
	  AND	PostponeOKForLowBandwidth = @PostponeOKForLowBandwidth
	  AND	PostponeOKForAnyReason = @PostponeOKForAnyReason
	  AND	Exclusive = @Exclusive
	  AND	Removable = @Removable
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[AllocationDetailsGetAll]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[AllocationDetailsGetAll]
GO
CREATE PROCEDURE [dbo].[AllocationDetailsGetAll]
AS
	SELECT	AllocationDetailsID,
		Action,
		EffectiveFrom,
		EffectiveFromIsLocal,
		EffectiveUntil,
		Wake,
		PostponeNoLaterThan,
		PostponeNoLaterThanIsLocal,
		PostponePeriod,
		PostponeLatest,
		PostponeOKForLowBandwidth,
		PostponeOKForAnyReason,
		Exclusive,
		Removable
	FROM	[dbo].[AllocationDetails]
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[AllocationDetailsAdd]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[AllocationDetailsAdd]
GO
CREATE PROCEDURE [dbo].[AllocationDetailsAdd]
	@Action			varchar(16) = NULL,
	@EffectiveFrom		datetime = NULL,
	@EffectiveFromIsLocal	bit = 1,
	@EffectiveUntil		datetime = NULL,
	@Wake			bit = 0,
	@PostponeNoLaterThan	datetime = NULL,
	@PostponeNoLaterThanIsLocal bit = 0,
	@PostponePeriod		int = NULL,
	@PostponeLatest		bit = 1,
	@PostponeOKForLowBandwidth bit = 1,
	@PostponeOKForAnyReason	bit = 1,
	@Exclusive		bit = 0,
	@Removable		bit = 0
AS
	INSERT INTO  dbo.AllocationDetails (
		Action,
		EffectiveFrom,
		EffectiveFromIsLocal,
		EffectiveUntil,
		Wake,
		PostponeNoLaterThan,
		PostponeNoLaterThanIsLocal,
		PostponePeriod,
		PostponeLatest,
		PostponeOKForLowBandwidth,
		PostponeOKForAnyReason,
		Exclusive,
		Removable
	)
	VALUES (
		@Action,
		@EffectiveFrom,
		@EffectiveFromIsLocal,
		@EffectiveUntil,
		@Wake,
		@PostponeNoLaterThan,
		@PostponeNoLaterThanIsLocal,
		@PostponePeriod,
		@PostponeLatest,
		@PostponeOKForLowBandwidth,
		@PostponeOKForAnyReason,
		@Exclusive,
		@Removable
	)
	RETURN SCOPE_IDENTITY()
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[AllocationDetailsBind]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[AllocationDetailsBind]
GO
CREATE PROCEDURE [dbo].[AllocationDetailsBind]
	@Action			varchar(16) = NULL,
	@EffectiveFrom		datetime = NULL,
	@EffectiveFromIsLocal	bit = 1,
	@EffectiveUntil		datetime = NULL,
	@Wake			bit = 0,
	@PostponeNoLaterThan	datetime = NULL,
	@PostponeNoLaterThanIsLocal bit = 0,
	@PostponePeriod		int = NULL,
	@PostponeLatest		bit = 1,
	@PostponeOKForLowBandwidth bit = 1,
	@PostponeOKForAnyReason	bit = 1,
	@Exclusive		bit = 0,
	@Removable		bit = 0
AS
	DECLARE	@ID	int

	SELECT	@ID = AllocationDetailsID
	FROM	[dbo].[AllocationDetails]
	WHERE	(Action = @Action OR (Action IS NULL AND @Action IS NULL))
	  AND	(EffectiveFrom = @EffectiveFrom OR (EffectiveFrom IS NULL AND @EffectiveFrom IS NULL))
	  AND	(EffectiveFromIsLocal = @EffectiveFromIsLocal OR (EffectiveFromIsLocal IS NULL AND @EffectiveFromIsLocal IS NULL))
	  AND	(EffectiveUntil = @EffectiveUntil OR (EffectiveUntil IS NULL AND @EffectiveUntil IS NULL))
	  AND	(Wake = @Wake OR (Wake IS NULL AND @Wake IS NULL))
	  AND	(PostponeNoLaterThan = @PostponeNoLaterThan OR (PostponeNoLaterThan IS NULL AND @PostponeNoLaterThan IS NULL))
	  AND	PostponeNoLaterThanIsLocal = @PostponeNoLaterThanIsLocal
	  AND	(PostponePeriod = @PostponePeriod OR (PostponePeriod IS NULL AND @PostponePeriod IS NULL))
	  AND	PostponeLatest = @PostponeLatest
	  AND	PostponeOKForLowBandwidth = @PostponeOKForLowBandwidth
	  AND	PostponeOKForAnyReason = @PostponeOKForAnyReason
	  AND	Exclusive = @Exclusive
	  AND	Removable = @Removable

	IF @ID IS NULL
		EXEC @ID = AllocationDetailsAdd @Action,
			@EffectiveFrom,
			@EffectiveFromIsLocal,
			@EffectiveUntil,
			@Wake,
			@PostponeNoLaterThan,
			@PostponeNoLaterThanIsLocal,
			@PostponePeriod,
			@PostponeLatest,
			@PostponeOKForLowBandwidth,
			@PostponeOKForAnyReason,
			@Exclusive,
			@Removable

	RETURN @ID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[AllocationDetailsSchema]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[AllocationDetailsSchema]
GO
CREATE PROCEDURE [dbo].[AllocationDetailsSchema]
AS
	SELECT
	'IF OBJECT_ID(''tempdb..#AllocationDetails'') IS NULL' + CAST(0x0A AS CHAR(1)) +
	'	CREATE TABLE #AllocationDetails (' + CAST(0x0A AS CHAR(1)) +
	'		AllocationDetailsID	int NULL,' + CAST(0x0A AS CHAR(1)) +
	'		Action			varchar(16) COLLATE database_default NULL,' + CAST(0x0A AS CHAR(1)) +
	'		EffectiveFrom		datetime NULL,' + CAST(0x0A AS CHAR(1)) +
	'		EffectiveFromIsLocal	bit NULL DEFAULT 1,' + CAST(0x0A AS CHAR(1)) +
	'		EffectiveUntil		datetime NULL,' + CAST(0x0A AS CHAR(1)) +
	'		Wake			bit NULL DEFAULT 0,' + CAST(0x0A AS CHAR(1)) +
	'		PostponeNoLaterThan	datetime NULL,' + CAST(0x0A AS CHAR(1)) +
	'		PostponeNoLaterThanIsLocal bit NOT NULL DEFAULT 0,' + CAST(0x0A AS CHAR(1)) +
	'		PostponePeriod		int NULL,' + CAST(0x0A AS CHAR(1)) +
	'		PostponeLatest		bit NOT NULL DEFAULT 1,' + CAST(0x0A AS CHAR(1)) +
	'		PostponeOKForLowBandwidth bit NOT NULL DEFAULT 1,' + CAST(0x0A AS CHAR(1)) +
	'		PostponeOKForAnyReason	bit NOT NULL DEFAULT 1,' + CAST(0x0A AS CHAR(1)) +
	'		Exclusive		bit NOT NULL DEFAULT 0,' + CAST(0x0A AS CHAR(1)) +
	'		Removable		bit NOT NULL DEFAULT 0' + CAST(0x0A AS CHAR(1)) +
	'	)' + CAST(0x0A AS CHAR(1)) +
	'ELSE' + CAST(0x0A AS CHAR(1)) +
	'	DELETE FROM #AllocationDetails' + CAST(0x0A AS CHAR(1)) +
	'' AS SQL
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[AllocationDetailsTempAdd]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[AllocationDetailsTempAdd]
GO
CREATE PROCEDURE dbo.[AllocationDetailsTempAdd]
	@AllocationDetailsID	int,
	@Action			varchar(16) = NULL,
	@EffectiveFrom		datetime = NULL,
	@EffectiveFromIsLocal	bit = 1,
	@EffectiveUntil		datetime = NULL,
	@Wake			bit = 0,
	@PostponeNoLaterThan	datetime = NULL,
	@PostponeNoLaterThanIsLocal bit = 0,
	@PostponePeriod		int = NULL,
	@PostponeLatest		bit = 1,
	@PostponeOKForLowBandwidth bit = 1,
	@PostponeOKForAnyReason	bit = 1,
	@Exclusive		bit = 0,
	@Removable		bit = 0
AS
	INSERT INTO #AllocationDetails (
		AllocationDetailsID,
		Action,
		EffectiveFrom,
		EffectiveFromIsLocal,
		EffectiveUntil,
		Wake,
		PostponeNoLaterThan,
		PostponeNoLaterThanIsLocal,
		PostponePeriod,
		PostponeLatest,
		PostponeOKForLowBandwidth,
		PostponeOKForAnyReason,
		Exclusive,
		Removable
	)
	VALUES (
		@AllocationDetailsID,
		@Action,
		@EffectiveFrom,
		@EffectiveFromIsLocal,
		@EffectiveUntil,
		@Wake,
		@PostponeNoLaterThan,
		@PostponeNoLaterThanIsLocal,
		@PostponePeriod,
		@PostponeLatest,
		@PostponeOKForLowBandwidth,
		@PostponeOKForAnyReason,
		@Exclusive,
		@Removable
	)
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[AllocationDetailsAddBatch]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[AllocationDetailsAddBatch]
GO
CREATE PROCEDURE dbo.[AllocationDetailsAddBatch]
AS
	DECLARE @count int
	INSERT dbo.AllocationDetails (
		Action,
		EffectiveFrom,
		EffectiveFromIsLocal,
		EffectiveUntil,
		Wake,
		PostponeNoLaterThan,
		PostponeNoLaterThanIsLocal,
		PostponePeriod,
		PostponeLatest,
		PostponeOKForLowBandwidth,
		PostponeOKForAnyReason,
		Exclusive,
		Removable
	)
		SELECT	Action,
			EffectiveFrom,
			EffectiveFromIsLocal,
			EffectiveUntil,
			Wake,
			PostponeNoLaterThan,
			PostponeNoLaterThanIsLocal,
			PostponePeriod,
			PostponeLatest,
			PostponeOKForLowBandwidth,
			PostponeOKForAnyReason,
			Exclusive,
			Removable
		FROM #AllocationDetails
	SET @count = @@ROWCOUNT
	DROP TABLE #AllocationDetails	-- Drop temporary table
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[AllocationDetailsUpdateByID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[AllocationDetailsUpdateByID]
GO
CREATE PROCEDURE [dbo].[AllocationDetailsUpdateByID]
	@AllocationDetailsID	int,
	@Action			varchar(16) = NULL,
	@EffectiveFrom		datetime = NULL,
	@EffectiveFromIsLocal	bit = 1,
	@EffectiveUntil		datetime = NULL,
	@Wake			bit = 0,
	@PostponeNoLaterThan	datetime = NULL,
	@PostponeNoLaterThanIsLocal bit = 0,
	@PostponePeriod		int = NULL,
	@PostponeLatest		bit = 1,
	@PostponeOKForLowBandwidth bit = 1,
	@PostponeOKForAnyReason	bit = 1,
	@Exclusive		bit = 0,
	@Removable		bit = 0
AS
	DECLARE	@ID	int
	SET @ID = 0

	UPDATE	[dbo].[AllocationDetails]
	SET	@ID = AllocationDetailsID,
		Action = @Action,
		EffectiveFrom = @EffectiveFrom,
		EffectiveFromIsLocal = @EffectiveFromIsLocal,
		EffectiveUntil = @EffectiveUntil,
		Wake = @Wake,
		PostponeNoLaterThan = @PostponeNoLaterThan,
		PostponeNoLaterThanIsLocal = @PostponeNoLaterThanIsLocal,
		PostponePeriod = @PostponePeriod,
		PostponeLatest = @PostponeLatest,
		PostponeOKForLowBandwidth = @PostponeOKForLowBandwidth,
		PostponeOKForAnyReason = @PostponeOKForAnyReason,
		Exclusive = @Exclusive,
		Removable = @Removable
	WHERE	AllocationDetailsID = @AllocationDetailsID
	RETURN @ID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[AllocationDetailsUpdateBatchByID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[AllocationDetailsUpdateBatchByID]
GO
CREATE PROCEDURE dbo.[AllocationDetailsUpdateBatchByID]
AS
	DECLARE @count int

	CREATE INDEX [TempAllocationDetailsID]
		ON #AllocationDetails (AllocationDetailsID)

	UPDATE	[dbo].[AllocationDetails]
	SET	Action = t.Action,
		EffectiveFrom = t.EffectiveFrom,
		EffectiveFromIsLocal = t.EffectiveFromIsLocal,
		EffectiveUntil = t.EffectiveUntil,
		Wake = t.Wake,
		PostponeNoLaterThan = t.PostponeNoLaterThan,
		PostponeNoLaterThanIsLocal = t.PostponeNoLaterThanIsLocal,
		PostponePeriod = t.PostponePeriod,
		PostponeLatest = t.PostponeLatest,
		PostponeOKForLowBandwidth = t.PostponeOKForLowBandwidth,
		PostponeOKForAnyReason = t.PostponeOKForAnyReason,
		Exclusive = t.Exclusive,
		Removable = t.Removable
	FROM	#AllocationDetails AS t
	WHERE	AllocationDetails.AllocationDetailsID = t.AllocationDetailsID
	SET @count = @@ROWCOUNT
	DROP TABLE #AllocationDetails	-- Drop the temporary table
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[AllocationDetailsPutByAll]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[AllocationDetailsPutByAll]
GO
CREATE PROCEDURE [dbo].[AllocationDetailsPutByAll]
	@Action			varchar(16) = NULL,
	@EffectiveFrom		datetime = NULL,
	@EffectiveFromIsLocal	bit = 1,
	@EffectiveUntil		datetime = NULL,
	@Wake			bit = 0,
	@PostponeNoLaterThan	datetime = NULL,
	@PostponeNoLaterThanIsLocal bit = 0,
	@PostponePeriod		int = NULL,
	@PostponeLatest		bit = 1,
	@PostponeOKForLowBandwidth bit = 1,
	@PostponeOKForAnyReason	bit = 1,
	@Exclusive		bit = 0,
	@Removable		bit = 0
AS
	DECLARE @ID	int

	SELECT	@ID = AllocationDetailsID
	FROM	AllocationDetails
	WHERE	(Action = @Action OR (Action IS NULL AND @Action IS NULL))
	  AND	(EffectiveFrom = @EffectiveFrom OR (EffectiveFrom IS NULL AND @EffectiveFrom IS NULL))
	  AND	(EffectiveFromIsLocal = @EffectiveFromIsLocal OR (EffectiveFromIsLocal IS NULL AND @EffectiveFromIsLocal IS NULL))
	  AND	(EffectiveUntil = @EffectiveUntil OR (EffectiveUntil IS NULL AND @EffectiveUntil IS NULL))
	  AND	(Wake = @Wake OR (Wake IS NULL AND @Wake IS NULL))
	  AND	(PostponeNoLaterThan = @PostponeNoLaterThan OR (PostponeNoLaterThan IS NULL AND @PostponeNoLaterThan IS NULL))
	  AND	PostponeNoLaterThanIsLocal = @PostponeNoLaterThanIsLocal
	  AND	(PostponePeriod = @PostponePeriod OR (PostponePeriod IS NULL AND @PostponePeriod IS NULL))
	  AND	PostponeLatest = @PostponeLatest
	  AND	PostponeOKForLowBandwidth = @PostponeOKForLowBandwidth
	  AND	PostponeOKForAnyReason = @PostponeOKForAnyReason
	  AND	Exclusive = @Exclusive
	  AND	Removable = @Removable

	IF @ID IS NULL
		EXEC @ID = AllocationDetailsAdd @Action,
			@EffectiveFrom,
			@EffectiveFromIsLocal,
			@EffectiveUntil,
			@Wake,
			@PostponeNoLaterThan,
			@PostponeNoLaterThanIsLocal,
			@PostponePeriod,
			@PostponeLatest,
			@PostponeOKForLowBandwidth,
			@PostponeOKForAnyReason,
			@Exclusive,
			@Removable

	RETURN @ID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[AllocationDetailsPutBatchByAll]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[AllocationDetailsPutBatchByAll]
GO
CREATE PROCEDURE [dbo].[AllocationDetailsPutBatchByAll]
AS
	DECLARE @count AS int
	SET @count = 0

	CREATE INDEX [TempAllocationDetailsAll]
		ON #AllocationDetails (Action, EffectiveFrom, EffectiveFromIsLocal, EffectiveUntil, Wake, PostponeNoLaterThan, PostponeNoLaterThanIsLocal, PostponePeriod, PostponeLatest, PostponeOKForLowBandwidth, PostponeOKForAnyReason, Exclusive, Removable)

	BEGIN TRANSACTION

	INSERT [dbo].[AllocationDetails] (
		Action,
		EffectiveFrom,
		EffectiveFromIsLocal,
		EffectiveUntil,
		Wake,
		PostponeNoLaterThan,
		PostponeNoLaterThanIsLocal,
		PostponePeriod,
		PostponeLatest,
		PostponeOKForLowBandwidth,
		PostponeOKForAnyReason,
		Exclusive,
		Removable
	)
		SELECT	Action,
			EffectiveFrom,
			EffectiveFromIsLocal,
			EffectiveUntil,
			Wake,
			PostponeNoLaterThan,
			PostponeNoLaterThanIsLocal,
			PostponePeriod,
			PostponeLatest,
			PostponeOKForLowBandwidth,
			PostponeOKForAnyReason,
			Exclusive,
			Removable
		FROM	#AllocationDetails AS t
		WHERE NOT EXISTS(	-- Current record doesn't exist
			SELECT * FROM [dbo].[AllocationDetails]
			WHERE	(AllocationDetails.Action = t.Action OR (AllocationDetails.Action IS NULL AND t.Action IS NULL))
			  AND	(AllocationDetails.EffectiveFrom = t.EffectiveFrom OR (AllocationDetails.EffectiveFrom IS NULL AND t.EffectiveFrom IS NULL))
			  AND	(AllocationDetails.EffectiveFromIsLocal = t.EffectiveFromIsLocal OR (AllocationDetails.EffectiveFromIsLocal IS NULL AND t.EffectiveFromIsLocal IS NULL))
			  AND	(AllocationDetails.EffectiveUntil = t.EffectiveUntil OR (AllocationDetails.EffectiveUntil IS NULL AND t.EffectiveUntil IS NULL))
			  AND	(AllocationDetails.Wake = t.Wake OR (AllocationDetails.Wake IS NULL AND t.Wake IS NULL))
			  AND	(AllocationDetails.PostponeNoLaterThan = t.PostponeNoLaterThan OR (AllocationDetails.PostponeNoLaterThan IS NULL AND t.PostponeNoLaterThan IS NULL))
			  AND	AllocationDetails.PostponeNoLaterThanIsLocal = t.PostponeNoLaterThanIsLocal
			  AND	(AllocationDetails.PostponePeriod = t.PostponePeriod OR (AllocationDetails.PostponePeriod IS NULL AND t.PostponePeriod IS NULL))
			  AND	AllocationDetails.PostponeLatest = t.PostponeLatest
			  AND	AllocationDetails.PostponeOKForLowBandwidth = t.PostponeOKForLowBandwidth
			  AND	AllocationDetails.PostponeOKForAnyReason = t.PostponeOKForAnyReason
			  AND	AllocationDetails.Exclusive = t.Exclusive
			  AND	AllocationDetails.Removable = t.Removable
		)
	SET @count = @count + @@ROWCOUNT
	DROP TABLE #AllocationDetails	-- Drop the temporary table
	COMMIT WORK
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[AllocationDetailsRemoveBatch]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[AllocationDetailsRemoveBatch]
GO

CREATE PROCEDURE [dbo].[AllocationDetailsRemoveBatch]
AS

	CREATE INDEX [TempAllocationDetailsAllocationDetailsRemoveBatch]
		ON #AllocationDetails (AllocationDetailsID)	

	-- Delete records from AllocationDetails identified by fields of [TempAllocationDetailsAllocationDetailsRemoveBatch]
	DELETE [dbo].[AllocationDetails]
	WHERE EXISTS(
			SELECT * FROM #AllocationDetails AS t
			WHERE	AllocationDetails.AllocationDetailsID = t.AllocationDetailsID
		)
	DROP TABLE #AllocationDetails      -- Drop the temporary table
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[AllocationDetailsRemoveByID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[AllocationDetailsRemoveByID]
GO
CREATE PROCEDURE [dbo].[AllocationDetailsRemoveByID]
	@AllocationDetailsID	int
AS
	-- AllocationDetails deletes cascade to:
	--	PackageAllocation by FK_Allocation_Details
	--	PackageApplies by FK_PackageApplies_AllocationDetails
	--	InstallationPostponement by FK_InstallationPostponement_AllocationDetails
	DELETE	[dbo].[AllocationDetails]
	WHERE	AllocationDetailsID = @AllocationDetailsID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[AllocationDetailsRemoveAll]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[AllocationDetailsRemoveAll]
GO
CREATE PROCEDURE [dbo].[AllocationDetailsRemoveAll]
	
AS
	DELETE	[dbo].[AllocationDetails]
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[PackageAllocationGetByPolicyGUIDTargetTypeIDPackagePathIDAllocationDetailsID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[PackageAllocationGetByPolicyGUIDTargetTypeIDPackagePathIDAllocationDetailsID]
GO
CREATE PROCEDURE [dbo].[PackageAllocationGetByPolicyGUIDTargetTypeIDPackagePathIDAllocationDetailsID]
	@PolicyGUID		binary(16),
	@TargetTypeID		int,
	@PackagePathID		int,
	@AllocationDetailsID	int
AS
	SELECT	PolicyGUID,
		PackagePathID,
		AccessGroupID,
		TargetTypeID,
		Precedence,
		AllocationDetailsID
	FROM	[dbo].[PackageAllocation]
	WHERE	PolicyGUID = @PolicyGUID
	  AND	TargetTypeID = @TargetTypeID
	  AND	PackagePathID = @PackagePathID
	  AND	AllocationDetailsID = @AllocationDetailsID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[PackageAllocationGetAllByPolicyGUIDTargetTypeIDPackagePathID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[PackageAllocationGetAllByPolicyGUIDTargetTypeIDPackagePathID]
GO
CREATE PROCEDURE [dbo].[PackageAllocationGetAllByPolicyGUIDTargetTypeIDPackagePathID]
	@PolicyGUID		binary(16),
	@TargetTypeID		int,
	@PackagePathID		int
AS
	SELECT	PolicyGUID,
		PackagePathID,
		AccessGroupID,
		TargetTypeID,
		Precedence,
		AllocationDetailsID
	FROM	[dbo].[PackageAllocation]
	WHERE	PolicyGUID = @PolicyGUID
	  AND	TargetTypeID = @TargetTypeID
	  AND	PackagePathID = @PackagePathID
	ORDER BY AllocationDetailsID
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[PackageAllocationGetAllByPolicyGUIDTargetTypeID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[PackageAllocationGetAllByPolicyGUIDTargetTypeID]
GO
CREATE PROCEDURE [dbo].[PackageAllocationGetAllByPolicyGUIDTargetTypeID]
	@PolicyGUID		binary(16),
	@TargetTypeID		int
AS
	SELECT	PolicyGUID,
		PackagePathID,
		AccessGroupID,
		TargetTypeID,
		Precedence,
		AllocationDetailsID
	FROM	[dbo].[PackageAllocation]
	WHERE	PolicyGUID = @PolicyGUID
	  AND	TargetTypeID = @TargetTypeID
	ORDER BY PackagePathID, AllocationDetailsID
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[PackageAllocationGetAllByPolicyGUID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[PackageAllocationGetAllByPolicyGUID]
GO
CREATE PROCEDURE [dbo].[PackageAllocationGetAllByPolicyGUID]
	@PolicyGUID		binary(16)
AS
	SELECT	PolicyGUID,
		PackagePathID,
		AccessGroupID,
		TargetTypeID,
		Precedence,
		AllocationDetailsID
	FROM	[dbo].[PackageAllocation]
	WHERE	PolicyGUID = @PolicyGUID
	ORDER BY TargetTypeID, PackagePathID, AllocationDetailsID
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[PackageAllocationGetAllByPackagePathID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[PackageAllocationGetAllByPackagePathID]
GO
CREATE PROCEDURE [dbo].[PackageAllocationGetAllByPackagePathID]
	@PackagePathID		int
AS
	SELECT	PolicyGUID,
		PackagePathID,
		AccessGroupID,
		TargetTypeID,
		Precedence,
		AllocationDetailsID
	FROM	[dbo].[PackageAllocation]
	WHERE	PackagePathID = @PackagePathID
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[PackageAllocationGetAll]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[PackageAllocationGetAll]
GO
CREATE PROCEDURE [dbo].[PackageAllocationGetAll]
AS
	SELECT	PolicyGUID,
		PackagePathID,
		AccessGroupID,
		TargetTypeID,
		Precedence,
		AllocationDetailsID
	FROM	[dbo].[PackageAllocation]
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[PackageAllocationAdd]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[PackageAllocationAdd]
GO
CREATE PROCEDURE [dbo].[PackageAllocationAdd]
	@PolicyGUID		binary(16),
	@PackagePathID		int,
	@AccessGroupID		int = NULL,
	@TargetTypeID		int,
	@Precedence		int = 0,
	@AllocationDetailsID	int
AS
	INSERT INTO  dbo.PackageAllocation (
		PolicyGUID,
		PackagePathID,
		AccessGroupID,
		TargetTypeID,
		Precedence,
		AllocationDetailsID
	)
	VALUES (
		@PolicyGUID,
		@PackagePathID,
		@AccessGroupID,
		@TargetTypeID,
		@Precedence,
		@AllocationDetailsID
	)
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[PackageAllocationSchema]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[PackageAllocationSchema]
GO
CREATE PROCEDURE [dbo].[PackageAllocationSchema]
AS
	SELECT
	'IF OBJECT_ID(''tempdb..#PackageAllocation'') IS NULL' + CAST(0x0A AS CHAR(1)) +
	'	CREATE TABLE #PackageAllocation (' + CAST(0x0A AS CHAR(1)) +
	'		PolicyGUID		binary(16) NOT NULL,' + CAST(0x0A AS CHAR(1)) +
	'		PackagePathID		int NOT NULL,' + CAST(0x0A AS CHAR(1)) +
	'		AccessGroupID		int NULL,' + CAST(0x0A AS CHAR(1)) +
	'		TargetTypeID		int NOT NULL,' + CAST(0x0A AS CHAR(1)) +
	'		Precedence		int NOT NULL DEFAULT 0,' + CAST(0x0A AS CHAR(1)) +
	'		AllocationDetailsID	int NOT NULL' + CAST(0x0A AS CHAR(1)) +
	'	)' + CAST(0x0A AS CHAR(1)) +
	'ELSE' + CAST(0x0A AS CHAR(1)) +
	'	DELETE FROM #PackageAllocation' + CAST(0x0A AS CHAR(1)) +
	'' AS SQL
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[PackageAllocationTempAdd]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[PackageAllocationTempAdd]
GO
CREATE PROCEDURE dbo.[PackageAllocationTempAdd]
	@PolicyGUID		binary(16),
	@PackagePathID		int,
	@AccessGroupID		int = NULL,
	@TargetTypeID		int,
	@Precedence		int = 0,
	@AllocationDetailsID	int
AS
	INSERT INTO #PackageAllocation (
		PolicyGUID,
		PackagePathID,
		AccessGroupID,
		TargetTypeID,
		Precedence,
		AllocationDetailsID
	)
	VALUES (
		@PolicyGUID,
		@PackagePathID,
		@AccessGroupID,
		@TargetTypeID,
		@Precedence,
		@AllocationDetailsID
	)
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[PackageAllocationAddBatch]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[PackageAllocationAddBatch]
GO
CREATE PROCEDURE dbo.[PackageAllocationAddBatch]
AS
	DECLARE @count int
	INSERT dbo.PackageAllocation (
		PolicyGUID,
		PackagePathID,
		AccessGroupID,
		TargetTypeID,
		Precedence,
		AllocationDetailsID
	)
		SELECT	PolicyGUID,
			PackagePathID,
			AccessGroupID,
			TargetTypeID,
			Precedence,
			AllocationDetailsID
		FROM #PackageAllocation
	SET @count = @@ROWCOUNT
	DROP TABLE #PackageAllocation	-- Drop temporary table
	RETURN @count
GO

/*
Add new PackageAllocation bound to
	Group using GUID with GroupOUID
	TargetType using TargetTypeName
	AllocationDetails using Action, EffectiveFrom, EffectiveFromIsLocal, EffectiveUntil, Wake, PostponeNoLaterThan, PostponeNoLaterThanIsLocal, PostponePeriod, PostponeLatest, PostponeOKForLowBandwidth, PostponeOKForAnyReason, Exclusive, Removable
	with PolicyGUID, PackagePathID, Precedence
*/

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[PackageAllocationUpdateByPolicyGUIDTargetTypeIDPackagePathIDAllocationDetailsID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[PackageAllocationUpdateByPolicyGUIDTargetTypeIDPackagePathIDAllocationDetailsID]
GO
CREATE PROCEDURE [dbo].[PackageAllocationUpdateByPolicyGUIDTargetTypeIDPackagePathIDAllocationDetailsID]
	@PolicyGUID		binary(16),
	@TargetTypeID		int,
	@PackagePathID		int,
	@AllocationDetailsID	int,
	@AccessGroupID		int = NULL,
	@Precedence		int = 0
AS
	UPDATE	[dbo].[PackageAllocation]
	SET	AccessGroupID = @AccessGroupID,
		Precedence = @Precedence
	WHERE	PolicyGUID = @PolicyGUID
	  AND	TargetTypeID = @TargetTypeID
	  AND	PackagePathID = @PackagePathID
	  AND	AllocationDetailsID = @AllocationDetailsID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[PackageAllocationUpdateBatchByPolicyGUIDTargetTypeIDPackagePathIDAllocationDetailsID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[PackageAllocationUpdateBatchByPolicyGUIDTargetTypeIDPackagePathIDAllocationDetailsID]
GO
CREATE PROCEDURE dbo.[PackageAllocationUpdateBatchByPolicyGUIDTargetTypeIDPackagePathIDAllocationDetailsID]
AS
	DECLARE @count int

	CREATE INDEX [TempPackageAllocationPolicyGUIDTargetTypeIDPackagePathIDAllocationDetailsID]
		ON #PackageAllocation (PolicyGUID, TargetTypeID, PackagePathID, AllocationDetailsID)

	UPDATE	[dbo].[PackageAllocation]
	SET	AccessGroupID = t.AccessGroupID,
		Precedence = t.Precedence
	FROM	#PackageAllocation AS t
	WHERE	PackageAllocation.PolicyGUID = t.PolicyGUID
	  AND	PackageAllocation.TargetTypeID = t.TargetTypeID
	  AND	PackageAllocation.PackagePathID = t.PackagePathID
	  AND	PackageAllocation.AllocationDetailsID = t.AllocationDetailsID
	SET @count = @@ROWCOUNT
	DROP TABLE #PackageAllocation	-- Drop the temporary table
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[PackageAllocationPutByPolicyGUIDTargetTypeIDPackagePathIDAllocationDetailsID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[PackageAllocationPutByPolicyGUIDTargetTypeIDPackagePathIDAllocationDetailsID]
GO
CREATE PROCEDURE [dbo].[PackageAllocationPutByPolicyGUIDTargetTypeIDPackagePathIDAllocationDetailsID]
	@PolicyGUID		binary(16),
	@TargetTypeID		int,
	@PackagePathID		int,
	@AllocationDetailsID	int,
	@AccessGroupID		int = NULL,
	@Precedence		int = 0
AS
	IF NOT EXISTS(
		SELECT	1
		FROM	dbo.PackageAllocation
		WHERE	PolicyGUID = @PolicyGUID
		  AND	TargetTypeID = @TargetTypeID
		  AND	PackagePathID = @PackagePathID
		  AND	AllocationDetailsID = @AllocationDetailsID
	)
		EXEC PackageAllocationAdd @PolicyGUID,
			@PackagePathID,
			@AccessGroupID,
			@TargetTypeID,
			@Precedence,
			@AllocationDetailsID
	ELSE
		EXEC PackageAllocationUpdateByPolicyGUIDTargetTypeIDPackagePathIDAllocationDetailsID @PolicyGUID,
			@TargetTypeID,
			@PackagePathID,
			@AllocationDetailsID,
			@AccessGroupID,
			@Precedence
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[PackageAllocationPutBatchByPolicyGUIDTargetTypeIDPackagePathIDAllocationDetailsID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[PackageAllocationPutBatchByPolicyGUIDTargetTypeIDPackagePathIDAllocationDetailsID]
GO
CREATE PROCEDURE [dbo].[PackageAllocationPutBatchByPolicyGUIDTargetTypeIDPackagePathIDAllocationDetailsID]
AS
	DECLARE @count AS int
	SET @count = 0

	CREATE INDEX [TempPackageAllocationPolicyGUIDTargetTypeIDPackagePathIDAllocationDetailsID]
		ON #PackageAllocation (PolicyGUID, TargetTypeID, PackagePathID, AllocationDetailsID)

	BEGIN TRANSACTION
	UPDATE [dbo].[PackageAllocation]
		SET	AccessGroupID = t.AccessGroupID,
			Precedence = t.Precedence
		FROM	#PackageAllocation AS t
		WHERE	PackageAllocation.PolicyGUID = t.PolicyGUID
		  AND	PackageAllocation.TargetTypeID = t.TargetTypeID
		  AND	PackageAllocation.PackagePathID = t.PackagePathID
		  AND	PackageAllocation.AllocationDetailsID = t.AllocationDetailsID
	SET @count = @@ROWCOUNT

	INSERT [dbo].[PackageAllocation] (
		PolicyGUID,
		PackagePathID,
		AccessGroupID,
		TargetTypeID,
		Precedence,
		AllocationDetailsID
	)
		SELECT	PolicyGUID,
			PackagePathID,
			AccessGroupID,
			TargetTypeID,
			Precedence,
			AllocationDetailsID
		FROM	#PackageAllocation AS t
		WHERE NOT EXISTS(	-- Current record doesn't exist
			SELECT * FROM [dbo].[PackageAllocation]
			WHERE	PackageAllocation.PolicyGUID = t.PolicyGUID
			  AND	PackageAllocation.TargetTypeID = t.TargetTypeID
			  AND	PackageAllocation.PackagePathID = t.PackagePathID
			  AND	PackageAllocation.AllocationDetailsID = t.AllocationDetailsID
		)
	SET @count = @count + @@ROWCOUNT
	DROP TABLE #PackageAllocation	-- Drop the temporary table
	COMMIT WORK
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[PackageAllocationRemoveBatch]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[PackageAllocationRemoveBatch]
GO

CREATE PROCEDURE [dbo].[PackageAllocationRemoveBatch]
AS

	CREATE INDEX [TempPackageAllocationPackageAllocationRemoveBatch]
		ON #PackageAllocation (PolicyGUID, TargetTypeID, PackagePathID, AllocationDetailsID)	

	-- Delete records from PackageAllocation identified by fields of [TempPackageAllocationPackageAllocationRemoveBatch]
	DELETE [dbo].[PackageAllocation]
	WHERE EXISTS(
			SELECT * FROM #PackageAllocation AS t
			WHERE	PackageAllocation.PolicyGUID = t.PolicyGUID
			  AND	PackageAllocation.TargetTypeID = t.TargetTypeID
			  AND	PackageAllocation.PackagePathID = t.PackagePathID
			  AND	PackageAllocation.AllocationDetailsID = t.AllocationDetailsID
		)
	DROP TABLE #PackageAllocation      -- Drop the temporary table
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[PackageAllocationRemoveByPolicyGUIDTargetTypeIDPackagePathIDAllocationDetailsID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[PackageAllocationRemoveByPolicyGUIDTargetTypeIDPackagePathIDAllocationDetailsID]
GO
CREATE PROCEDURE [dbo].[PackageAllocationRemoveByPolicyGUIDTargetTypeIDPackagePathIDAllocationDetailsID]
	@PolicyGUID		binary(16),
	@TargetTypeID		int,
	@PackagePathID		int,
	@AllocationDetailsID	int
AS
	DELETE	[dbo].[PackageAllocation]
	WHERE	PolicyGUID = @PolicyGUID
	  AND	TargetTypeID = @TargetTypeID
	  AND	PackagePathID = @PackagePathID
	  AND	AllocationDetailsID = @AllocationDetailsID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[PackageAllocationRemoveAllByPolicyGUIDTargetTypeIDPackagePathID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[PackageAllocationRemoveAllByPolicyGUIDTargetTypeIDPackagePathID]
GO
CREATE PROCEDURE [dbo].[PackageAllocationRemoveAllByPolicyGUIDTargetTypeIDPackagePathID]
	@PolicyGUID		binary(16),
	@TargetTypeID		int,
	@PackagePathID		int
AS
	DELETE	[dbo].[PackageAllocation]
	WHERE	PolicyGUID = @PolicyGUID
	  AND	TargetTypeID = @TargetTypeID
	  AND	PackagePathID = @PackagePathID
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[PackageAllocationRemoveAllByPolicyGUIDTargetTypeID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[PackageAllocationRemoveAllByPolicyGUIDTargetTypeID]
GO
CREATE PROCEDURE [dbo].[PackageAllocationRemoveAllByPolicyGUIDTargetTypeID]
	@PolicyGUID		binary(16),
	@TargetTypeID		int
AS
	DELETE	[dbo].[PackageAllocation]
	WHERE	PolicyGUID = @PolicyGUID
	  AND	TargetTypeID = @TargetTypeID
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[PackageAllocationRemoveAllByPolicyGUID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[PackageAllocationRemoveAllByPolicyGUID]
GO
CREATE PROCEDURE [dbo].[PackageAllocationRemoveAllByPolicyGUID]
	@PolicyGUID		binary(16)
AS
	DELETE	[dbo].[PackageAllocation]
	WHERE	PolicyGUID = @PolicyGUID
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[PackageAllocationRemoveAll]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[PackageAllocationRemoveAll]
GO
CREATE PROCEDURE [dbo].[PackageAllocationRemoveAll]
	
AS
	DELETE	[dbo].[PackageAllocation]
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[PackageAllocationReplaceSubsetByPolicyGUIDTargetTypeIDPackagePathID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[PackageAllocationReplaceSubsetByPolicyGUIDTargetTypeIDPackagePathID]
GO
-- Replace the record subset selected by (@PolicyGUID, @TargetTypeID, @PackagePathID)
-- using unique identifier (PolicyGUID, TargetTypeID, PackagePathID, AllocationDetailsID)
-- updating fields (AccessGroupID, Precedence)
CREATE PROCEDURE [dbo].[PackageAllocationReplaceSubsetByPolicyGUIDTargetTypeIDPackagePathID]
	@PolicyGUID		binary(16),
	@TargetTypeID		int,
	@PackagePathID		int
AS
	DECLARE @count AS int
	SET @count = 0

	CREATE INDEX [TempPackageAllocationByPolicyGUIDTargetTypeIDPackagePathID]
		ON #PackageAllocation (PolicyGUID, TargetTypeID, PackagePathID, AllocationDetailsID)

	BEGIN TRANSACTION
	DELETE [PackageAllocation]
		WHERE	PolicyGUID = @PolicyGUID
		  AND	TargetTypeID = @TargetTypeID
		  AND	PackagePathID = @PackagePathID
		AND NOT EXISTS(		-- Replacement record doesn't exist
			SELECT * FROM #PackageAllocation AS t
			WHERE	PackageAllocation.PolicyGUID = t.PolicyGUID
			  AND	PackageAllocation.TargetTypeID = t.TargetTypeID
			  AND	PackageAllocation.PackagePathID = t.PackagePathID
			  AND	PackageAllocation.AllocationDetailsID = t.AllocationDetailsID
		)

	UPDATE [dbo].[PackageAllocation]
		SET	AccessGroupID = t.AccessGroupID,
			Precedence = t.Precedence
		FROM	#PackageAllocation AS t
		WHERE	PackageAllocation.PolicyGUID = t.PolicyGUID
		  AND	PackageAllocation.TargetTypeID = t.TargetTypeID
		  AND	PackageAllocation.PackagePathID = t.PackagePathID
		  AND	PackageAllocation.AllocationDetailsID = t.AllocationDetailsID
	SET @count = @@ROWCOUNT

	INSERT [PackageAllocation] (
		PolicyGUID,
		PackagePathID,
		AccessGroupID,
		TargetTypeID,
		Precedence,
		AllocationDetailsID
	)
		SELECT	PolicyGUID,
			PackagePathID,
			AccessGroupID,
			TargetTypeID,
			Precedence,
			AllocationDetailsID
		FROM	#PackageAllocation AS t
		WHERE NOT EXISTS(	-- Current record doesn't exist
			SELECT * FROM [PackageAllocation]
			WHERE	PackageAllocation.PolicyGUID = t.PolicyGUID
			  AND	PackageAllocation.TargetTypeID = t.TargetTypeID
			  AND	PackageAllocation.PackagePathID = t.PackagePathID
			  AND	PackageAllocation.AllocationDetailsID = t.AllocationDetailsID
		)
	SET @count = @count + @@ROWCOUNT
	DROP TABLE #PackageAllocation	-- Drop the temporary table
	COMMIT WORK
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[PackageAllocationReplaceSubsetByPolicyGUIDTargetTypeID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[PackageAllocationReplaceSubsetByPolicyGUIDTargetTypeID]
GO
-- Replace the record subset selected by (@PolicyGUID, @TargetTypeID)
-- using unique identifier (PolicyGUID, TargetTypeID, PackagePathID, AllocationDetailsID)
-- updating fields (AccessGroupID, Precedence)
CREATE PROCEDURE [dbo].[PackageAllocationReplaceSubsetByPolicyGUIDTargetTypeID]
	@PolicyGUID		binary(16),
	@TargetTypeID		int
AS
	DECLARE @count AS int
	SET @count = 0

	CREATE INDEX [TempPackageAllocationByPolicyGUIDTargetTypeID]
		ON #PackageAllocation (PolicyGUID, TargetTypeID, PackagePathID, AllocationDetailsID)

	BEGIN TRANSACTION
	DELETE [PackageAllocation]
		WHERE	PolicyGUID = @PolicyGUID
		  AND	TargetTypeID = @TargetTypeID
		AND NOT EXISTS(		-- Replacement record doesn't exist
			SELECT * FROM #PackageAllocation AS t
			WHERE	PackageAllocation.PolicyGUID = t.PolicyGUID
			  AND	PackageAllocation.TargetTypeID = t.TargetTypeID
			  AND	PackageAllocation.PackagePathID = t.PackagePathID
			  AND	PackageAllocation.AllocationDetailsID = t.AllocationDetailsID
		)

	UPDATE [dbo].[PackageAllocation]
		SET	AccessGroupID = t.AccessGroupID,
			Precedence = t.Precedence
		FROM	#PackageAllocation AS t
		WHERE	PackageAllocation.PolicyGUID = t.PolicyGUID
		  AND	PackageAllocation.TargetTypeID = t.TargetTypeID
		  AND	PackageAllocation.PackagePathID = t.PackagePathID
		  AND	PackageAllocation.AllocationDetailsID = t.AllocationDetailsID
	SET @count = @@ROWCOUNT

	INSERT [PackageAllocation] (
		PolicyGUID,
		PackagePathID,
		AccessGroupID,
		TargetTypeID,
		Precedence,
		AllocationDetailsID
	)
		SELECT	PolicyGUID,
			PackagePathID,
			AccessGroupID,
			TargetTypeID,
			Precedence,
			AllocationDetailsID
		FROM	#PackageAllocation AS t
		WHERE NOT EXISTS(	-- Current record doesn't exist
			SELECT * FROM [PackageAllocation]
			WHERE	PackageAllocation.PolicyGUID = t.PolicyGUID
			  AND	PackageAllocation.TargetTypeID = t.TargetTypeID
			  AND	PackageAllocation.PackagePathID = t.PackagePathID
			  AND	PackageAllocation.AllocationDetailsID = t.AllocationDetailsID
		)
	SET @count = @count + @@ROWCOUNT
	DROP TABLE #PackageAllocation	-- Drop the temporary table
	COMMIT WORK
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[PackageAllocationReplaceSubsetByPolicyGUID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[PackageAllocationReplaceSubsetByPolicyGUID]
GO
-- Replace the record subset selected by (@PolicyGUID)
-- using unique identifier (PolicyGUID, TargetTypeID, PackagePathID, AllocationDetailsID)
-- updating fields (AccessGroupID, Precedence)
CREATE PROCEDURE [dbo].[PackageAllocationReplaceSubsetByPolicyGUID]
	@PolicyGUID		binary(16)
AS
	DECLARE @count AS int
	SET @count = 0

	CREATE INDEX [TempPackageAllocationByPolicyGUID]
		ON #PackageAllocation (PolicyGUID, TargetTypeID, PackagePathID, AllocationDetailsID)

	BEGIN TRANSACTION
	DELETE [PackageAllocation]
		WHERE	PolicyGUID = @PolicyGUID
		AND NOT EXISTS(		-- Replacement record doesn't exist
			SELECT * FROM #PackageAllocation AS t
			WHERE	PackageAllocation.PolicyGUID = t.PolicyGUID
			  AND	PackageAllocation.TargetTypeID = t.TargetTypeID
			  AND	PackageAllocation.PackagePathID = t.PackagePathID
			  AND	PackageAllocation.AllocationDetailsID = t.AllocationDetailsID
		)

	UPDATE [dbo].[PackageAllocation]
		SET	AccessGroupID = t.AccessGroupID,
			Precedence = t.Precedence
		FROM	#PackageAllocation AS t
		WHERE	PackageAllocation.PolicyGUID = t.PolicyGUID
		  AND	PackageAllocation.TargetTypeID = t.TargetTypeID
		  AND	PackageAllocation.PackagePathID = t.PackagePathID
		  AND	PackageAllocation.AllocationDetailsID = t.AllocationDetailsID
	SET @count = @@ROWCOUNT

	INSERT [PackageAllocation] (
		PolicyGUID,
		PackagePathID,
		AccessGroupID,
		TargetTypeID,
		Precedence,
		AllocationDetailsID
	)
		SELECT	PolicyGUID,
			PackagePathID,
			AccessGroupID,
			TargetTypeID,
			Precedence,
			AllocationDetailsID
		FROM	#PackageAllocation AS t
		WHERE NOT EXISTS(	-- Current record doesn't exist
			SELECT * FROM [PackageAllocation]
			WHERE	PackageAllocation.PolicyGUID = t.PolicyGUID
			  AND	PackageAllocation.TargetTypeID = t.TargetTypeID
			  AND	PackageAllocation.PackagePathID = t.PackagePathID
			  AND	PackageAllocation.AllocationDetailsID = t.AllocationDetailsID
		)
	SET @count = @count + @@ROWCOUNT
	DROP TABLE #PackageAllocation	-- Drop the temporary table
	COMMIT WORK
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[PolicyAppliesGetByTargetOUIDTargetTypeIDTargetIDGUID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[PolicyAppliesGetByTargetOUIDTargetTypeIDTargetIDGUID]
GO
CREATE PROCEDURE [dbo].[PolicyAppliesGetByTargetOUIDTargetTypeIDTargetIDGUID]
	@TargetOUID		int,
	@TargetTypeID		int,
	@TargetID		int,
	@GUID			binary(16)
AS
	SELECT	DomainID,
		TargetOUID,
		TargetTypeID,
		TargetID,
		GUID
	FROM	[dbo].[PolicyApplies]
	WHERE	TargetOUID = @TargetOUID
	  AND	TargetTypeID = @TargetTypeID
	  AND	TargetID = @TargetID
	  AND	GUID = @GUID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[PolicyAppliesGetAllByGUID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[PolicyAppliesGetAllByGUID]
GO
CREATE PROCEDURE [dbo].[PolicyAppliesGetAllByGUID]
	@GUID			binary(16)
AS
	SELECT	DomainID,
		TargetOUID,
		TargetTypeID,
		TargetID,
		GUID
	FROM	[dbo].[PolicyApplies]
	WHERE	GUID = @GUID
	ORDER BY TargetOUID
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[PolicyAppliesGetAllByDomainID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[PolicyAppliesGetAllByDomainID]
GO
CREATE PROCEDURE [dbo].[PolicyAppliesGetAllByDomainID]
	@DomainID		int
AS
	SELECT	DomainID,
		TargetOUID,
		TargetTypeID,
		TargetID,
		GUID
	FROM	[dbo].[PolicyApplies]
	WHERE	DomainID = @DomainID
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[PolicyAppliesGetAll]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[PolicyAppliesGetAll]
GO
CREATE PROCEDURE [dbo].[PolicyAppliesGetAll]
AS
	SELECT	DomainID,
		TargetOUID,
		TargetTypeID,
		TargetID,
		GUID
	FROM	[dbo].[PolicyApplies]
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[PolicyAppliesAdd]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[PolicyAppliesAdd]
GO
CREATE PROCEDURE [dbo].[PolicyAppliesAdd]
	@DomainID		int,
	@TargetOUID		int,
	@TargetTypeID		int,
	@TargetID		int,
	@GUID			binary(16)
AS
	INSERT INTO  dbo.PolicyApplies (
		DomainID,
		TargetOUID,
		TargetTypeID,
		TargetID,
		GUID
	)
	VALUES (
		@DomainID,
		@TargetOUID,
		@TargetTypeID,
		@TargetID,
		@GUID
	)
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[PolicyAppliesSchema]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[PolicyAppliesSchema]
GO
CREATE PROCEDURE [dbo].[PolicyAppliesSchema]
AS
	SELECT
	'IF OBJECT_ID(''tempdb..#PolicyApplies'') IS NULL' + CAST(0x0A AS CHAR(1)) +
	'	CREATE TABLE #PolicyApplies (' + CAST(0x0A AS CHAR(1)) +
	'		DomainID		int NOT NULL,' + CAST(0x0A AS CHAR(1)) +
	'		TargetOUID		int NOT NULL,' + CAST(0x0A AS CHAR(1)) +
	'		TargetTypeID		int NOT NULL,' + CAST(0x0A AS CHAR(1)) +
	'		TargetID		int NOT NULL,' + CAST(0x0A AS CHAR(1)) +
	'		GUID			binary(16) NOT NULL' + CAST(0x0A AS CHAR(1)) +
	'	)' + CAST(0x0A AS CHAR(1)) +
	'ELSE' + CAST(0x0A AS CHAR(1)) +
	'	DELETE FROM #PolicyApplies' + CAST(0x0A AS CHAR(1)) +
	'' AS SQL
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[PolicyAppliesTempAdd]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[PolicyAppliesTempAdd]
GO
CREATE PROCEDURE dbo.[PolicyAppliesTempAdd]
	@DomainID		int,
	@TargetOUID		int,
	@TargetTypeID		int,
	@TargetID		int,
	@GUID			binary(16)
AS
	INSERT INTO #PolicyApplies (
		DomainID,
		TargetOUID,
		TargetTypeID,
		TargetID,
		GUID
	)
	VALUES (
		@DomainID,
		@TargetOUID,
		@TargetTypeID,
		@TargetID,
		@GUID
	)
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[PolicyAppliesAddBatch]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[PolicyAppliesAddBatch]
GO
CREATE PROCEDURE dbo.[PolicyAppliesAddBatch]
AS
	DECLARE @count int
	INSERT dbo.PolicyApplies (
		DomainID,
		TargetOUID,
		TargetTypeID,
		TargetID,
		GUID
	)
		SELECT	DomainID,
			TargetOUID,
			TargetTypeID,
			TargetID,
			GUID
		FROM #PolicyApplies
	SET @count = @@ROWCOUNT
	DROP TABLE #PolicyApplies	-- Drop temporary table
	RETURN @count
GO

/*
Add new PolicyApplies bound to
	Organization using DomainID, RDN
	TargetType using TargetTypeName
	with DomainID, TargetID, GUID
*/

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[PolicyAppliesUpdateByTargetOUIDTargetTypeIDTargetIDGUID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[PolicyAppliesUpdateByTargetOUIDTargetTypeIDTargetIDGUID]
GO
CREATE PROCEDURE [dbo].[PolicyAppliesUpdateByTargetOUIDTargetTypeIDTargetIDGUID]
	@TargetOUID		int,
	@TargetTypeID		int,
	@TargetID		int,
	@GUID			binary(16),
	@DomainID		int
AS
	UPDATE	[dbo].[PolicyApplies]
	SET	DomainID = @DomainID
	WHERE	TargetOUID = @TargetOUID
	  AND	TargetTypeID = @TargetTypeID
	  AND	TargetID = @TargetID
	  AND	GUID = @GUID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[PolicyAppliesUpdateBatchByTargetOUIDTargetTypeIDTargetIDGUID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[PolicyAppliesUpdateBatchByTargetOUIDTargetTypeIDTargetIDGUID]
GO
CREATE PROCEDURE dbo.[PolicyAppliesUpdateBatchByTargetOUIDTargetTypeIDTargetIDGUID]
AS
	DECLARE @count int

	CREATE INDEX [TempPolicyAppliesTargetOUIDTargetTypeIDTargetIDGUID]
		ON #PolicyApplies (TargetOUID, TargetTypeID, TargetID, GUID)

	UPDATE	[dbo].[PolicyApplies]
	SET	DomainID = t.DomainID
	FROM	#PolicyApplies AS t
	WHERE	PolicyApplies.TargetOUID = t.TargetOUID
	  AND	PolicyApplies.TargetTypeID = t.TargetTypeID
	  AND	PolicyApplies.TargetID = t.TargetID
	  AND	PolicyApplies.GUID = t.GUID
	SET @count = @@ROWCOUNT
	DROP TABLE #PolicyApplies	-- Drop the temporary table
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[PolicyAppliesPutByTargetOUIDTargetTypeIDTargetIDGUID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[PolicyAppliesPutByTargetOUIDTargetTypeIDTargetIDGUID]
GO
CREATE PROCEDURE [dbo].[PolicyAppliesPutByTargetOUIDTargetTypeIDTargetIDGUID]
	@TargetOUID		int,
	@TargetTypeID		int,
	@TargetID		int,
	@GUID			binary(16),
	@DomainID		int
AS
	IF NOT EXISTS(
		SELECT	1
		FROM	dbo.PolicyApplies
		WHERE	TargetOUID = @TargetOUID
		  AND	TargetTypeID = @TargetTypeID
		  AND	TargetID = @TargetID
		  AND	GUID = @GUID
	)
		EXEC PolicyAppliesAdd @DomainID,
			@TargetOUID,
			@TargetTypeID,
			@TargetID,
			@GUID
	ELSE
		EXEC PolicyAppliesUpdateByTargetOUIDTargetTypeIDTargetIDGUID @TargetOUID,
			@TargetTypeID,
			@TargetID,
			@GUID,
			@DomainID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[PolicyAppliesPutBatchByTargetOUIDTargetTypeIDTargetIDGUID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[PolicyAppliesPutBatchByTargetOUIDTargetTypeIDTargetIDGUID]
GO
CREATE PROCEDURE [dbo].[PolicyAppliesPutBatchByTargetOUIDTargetTypeIDTargetIDGUID]
AS
	DECLARE @count AS int
	SET @count = 0

	CREATE INDEX [TempPolicyAppliesTargetOUIDTargetTypeIDTargetIDGUID]
		ON #PolicyApplies (TargetOUID, TargetTypeID, TargetID, GUID)

	BEGIN TRANSACTION
	UPDATE [dbo].[PolicyApplies]
		SET	DomainID = t.DomainID
		FROM	#PolicyApplies AS t
		WHERE	PolicyApplies.TargetOUID = t.TargetOUID
		  AND	PolicyApplies.TargetTypeID = t.TargetTypeID
		  AND	PolicyApplies.TargetID = t.TargetID
		  AND	PolicyApplies.GUID = t.GUID
	SET @count = @@ROWCOUNT

	INSERT [dbo].[PolicyApplies] (
		DomainID,
		TargetOUID,
		TargetTypeID,
		TargetID,
		GUID
	)
		SELECT	DomainID,
			TargetOUID,
			TargetTypeID,
			TargetID,
			GUID
		FROM	#PolicyApplies AS t
		WHERE NOT EXISTS(	-- Current record doesn't exist
			SELECT * FROM [dbo].[PolicyApplies]
			WHERE	PolicyApplies.TargetOUID = t.TargetOUID
			  AND	PolicyApplies.TargetTypeID = t.TargetTypeID
			  AND	PolicyApplies.TargetID = t.TargetID
			  AND	PolicyApplies.GUID = t.GUID
		)
	SET @count = @count + @@ROWCOUNT
	DROP TABLE #PolicyApplies	-- Drop the temporary table
	COMMIT WORK
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[PolicyAppliesRemoveBatch]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[PolicyAppliesRemoveBatch]
GO

CREATE PROCEDURE [dbo].[PolicyAppliesRemoveBatch]
AS

	CREATE INDEX [TempPolicyAppliesPolicyAppliesRemoveBatch]
		ON #PolicyApplies (TargetOUID, TargetTypeID, TargetID, GUID)	

	-- Delete records from PolicyApplies identified by fields of [TempPolicyAppliesPolicyAppliesRemoveBatch]
	DELETE [dbo].[PolicyApplies]
	WHERE EXISTS(
			SELECT * FROM #PolicyApplies AS t
			WHERE	PolicyApplies.TargetOUID = t.TargetOUID
			  AND	PolicyApplies.TargetTypeID = t.TargetTypeID
			  AND	PolicyApplies.TargetID = t.TargetID
			  AND	PolicyApplies.GUID = t.GUID
		)
	DROP TABLE #PolicyApplies      -- Drop the temporary table
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[PolicyAppliesRemoveByTargetOUIDTargetTypeIDTargetIDGUID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[PolicyAppliesRemoveByTargetOUIDTargetTypeIDTargetIDGUID]
GO
CREATE PROCEDURE [dbo].[PolicyAppliesRemoveByTargetOUIDTargetTypeIDTargetIDGUID]
	@TargetOUID		int,
	@TargetTypeID		int,
	@TargetID		int,
	@GUID			binary(16)
AS
	DELETE	[dbo].[PolicyApplies]
	WHERE	TargetOUID = @TargetOUID
	  AND	TargetTypeID = @TargetTypeID
	  AND	TargetID = @TargetID
	  AND	GUID = @GUID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[PolicyAppliesRemoveAllByDomainID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[PolicyAppliesRemoveAllByDomainID]
GO
CREATE PROCEDURE [dbo].[PolicyAppliesRemoveAllByDomainID]
	@DomainID		int
AS
	DELETE	[dbo].[PolicyApplies]
	WHERE	DomainID = @DomainID
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[PolicyAppliesRemoveAll]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[PolicyAppliesRemoveAll]
GO
CREATE PROCEDURE [dbo].[PolicyAppliesRemoveAll]
	
AS
	DELETE	[dbo].[PolicyApplies]
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[PolicyAppliesReplaceSubsetByDomainID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[PolicyAppliesReplaceSubsetByDomainID]
GO
-- Replace the record subset selected by (@DomainID)
-- using unique identifier (TargetOUID, TargetTypeID, TargetID, GUID)
CREATE PROCEDURE [dbo].[PolicyAppliesReplaceSubsetByDomainID]
	@DomainID		int
AS
	DECLARE @count AS int
	SET @count = 0

	CREATE INDEX [TempPolicyAppliesByDomainID]
		ON #PolicyApplies (TargetOUID, TargetTypeID, TargetID, GUID)

	BEGIN TRANSACTION
	DELETE [PolicyApplies]
		WHERE	DomainID = @DomainID
		AND NOT EXISTS(		-- Replacement record doesn't exist
			SELECT * FROM #PolicyApplies AS t
			WHERE	PolicyApplies.TargetOUID = t.TargetOUID
			  AND	PolicyApplies.TargetTypeID = t.TargetTypeID
			  AND	PolicyApplies.TargetID = t.TargetID
			  AND	PolicyApplies.GUID = t.GUID
		)

	INSERT [PolicyApplies] (
		DomainID,
		TargetOUID,
		TargetTypeID,
		TargetID,
		GUID
	)
		SELECT	DomainID,
			TargetOUID,
			TargetTypeID,
			TargetID,
			GUID
		FROM	#PolicyApplies AS t
		WHERE NOT EXISTS(	-- Current record doesn't exist
			SELECT * FROM [PolicyApplies]
			WHERE	PolicyApplies.TargetOUID = t.TargetOUID
			  AND	PolicyApplies.TargetTypeID = t.TargetTypeID
			  AND	PolicyApplies.TargetID = t.TargetID
			  AND	PolicyApplies.GUID = t.GUID
		)
	SET @count = @count + @@ROWCOUNT
	DROP TABLE #PolicyApplies	-- Drop the temporary table
	COMMIT WORK
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[PackageAppliesGetByTargetOUIDTargetTypeIDTargetIDPackagePathIDPolicyGUID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[PackageAppliesGetByTargetOUIDTargetTypeIDTargetIDPackagePathIDPolicyGUID]
GO
CREATE PROCEDURE [dbo].[PackageAppliesGetByTargetOUIDTargetTypeIDTargetIDPackagePathIDPolicyGUID]
	@TargetOUID		int,
	@TargetTypeID		int,
	@TargetID		int,
	@PackagePathID		int,
	@PolicyGUID		binary(16)
AS
	SELECT	TargetTypeID,
		TargetOUID,
		TargetID,
		PackagePathID,
		PolicyGUID,
		AllocationDetailsID,
		Precedence,
		PolicyVersion
	FROM	[dbo].[PackageApplies]
	WHERE	TargetOUID = @TargetOUID
	  AND	TargetTypeID = @TargetTypeID
	  AND	TargetID = @TargetID
	  AND	PackagePathID = @PackagePathID
	  AND	PolicyGUID = @PolicyGUID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[PackageAppliesGetAllByTargetOUIDTargetTypeIDTargetIDPackagePathID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[PackageAppliesGetAllByTargetOUIDTargetTypeIDTargetIDPackagePathID]
GO
CREATE PROCEDURE [dbo].[PackageAppliesGetAllByTargetOUIDTargetTypeIDTargetIDPackagePathID]
	@TargetOUID		int,
	@TargetTypeID		int,
	@TargetID		int,
	@PackagePathID		int
AS
	SELECT	TargetTypeID,
		TargetOUID,
		TargetID,
		PackagePathID,
		PolicyGUID,
		AllocationDetailsID,
		Precedence,
		PolicyVersion
	FROM	[dbo].[PackageApplies]
	WHERE	TargetOUID = @TargetOUID
	  AND	TargetTypeID = @TargetTypeID
	  AND	TargetID = @TargetID
	  AND	PackagePathID = @PackagePathID
	ORDER BY PolicyGUID
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[PackageAppliesGetAll]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[PackageAppliesGetAll]
GO
CREATE PROCEDURE [dbo].[PackageAppliesGetAll]
AS
	SELECT	TargetTypeID,
		TargetOUID,
		TargetID,
		PackagePathID,
		PolicyGUID,
		AllocationDetailsID,
		Precedence,
		PolicyVersion
	FROM	[dbo].[PackageApplies]
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[PackageAppliesAdd]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[PackageAppliesAdd]
GO
CREATE PROCEDURE [dbo].[PackageAppliesAdd]
	@TargetTypeID		int,
	@TargetOUID		int,
	@TargetID		int,
	@PackagePathID		int,
	@PolicyGUID		binary(16),
	@AllocationDetailsID	int,
	@Precedence		int = 0,
	@PolicyVersion		int = 0
AS
	INSERT INTO  dbo.PackageApplies (
		TargetTypeID,
		TargetOUID,
		TargetID,
		PackagePathID,
		PolicyGUID,
		AllocationDetailsID,
		Precedence,
		PolicyVersion
	)
	VALUES (
		@TargetTypeID,
		@TargetOUID,
		@TargetID,
		@PackagePathID,
		@PolicyGUID,
		@AllocationDetailsID,
		@Precedence,
		@PolicyVersion
	)
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[PackageAppliesSchema]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[PackageAppliesSchema]
GO
CREATE PROCEDURE [dbo].[PackageAppliesSchema]
AS
	SELECT
	'IF OBJECT_ID(''tempdb..#PackageApplies'') IS NULL' + CAST(0x0A AS CHAR(1)) +
	'	CREATE TABLE #PackageApplies (' + CAST(0x0A AS CHAR(1)) +
	'		TargetTypeID		int NOT NULL,' + CAST(0x0A AS CHAR(1)) +
	'		TargetOUID		int NOT NULL,' + CAST(0x0A AS CHAR(1)) +
	'		TargetID		int NOT NULL,' + CAST(0x0A AS CHAR(1)) +
	'		PackagePathID		int NOT NULL,' + CAST(0x0A AS CHAR(1)) +
	'		PolicyGUID		binary(16) NOT NULL,' + CAST(0x0A AS CHAR(1)) +
	'		AllocationDetailsID	int NOT NULL,' + CAST(0x0A AS CHAR(1)) +
	'		Precedence		int NOT NULL DEFAULT 0,' + CAST(0x0A AS CHAR(1)) +
	'		PolicyVersion		int NOT NULL DEFAULT 0' + CAST(0x0A AS CHAR(1)) +
	'	)' + CAST(0x0A AS CHAR(1)) +
	'ELSE' + CAST(0x0A AS CHAR(1)) +
	'	DELETE FROM #PackageApplies' + CAST(0x0A AS CHAR(1)) +
	'' AS SQL
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[PackageAppliesTempAdd]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[PackageAppliesTempAdd]
GO
CREATE PROCEDURE dbo.[PackageAppliesTempAdd]
	@TargetTypeID		int,
	@TargetOUID		int,
	@TargetID		int,
	@PackagePathID		int,
	@PolicyGUID		binary(16),
	@AllocationDetailsID	int,
	@Precedence		int = 0,
	@PolicyVersion		int = 0
AS
	INSERT INTO #PackageApplies (
		TargetTypeID,
		TargetOUID,
		TargetID,
		PackagePathID,
		PolicyGUID,
		AllocationDetailsID,
		Precedence,
		PolicyVersion
	)
	VALUES (
		@TargetTypeID,
		@TargetOUID,
		@TargetID,
		@PackagePathID,
		@PolicyGUID,
		@AllocationDetailsID,
		@Precedence,
		@PolicyVersion
	)
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[PackageAppliesAddBatch]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[PackageAppliesAddBatch]
GO
CREATE PROCEDURE dbo.[PackageAppliesAddBatch]
AS
	DECLARE @count int
	INSERT dbo.PackageApplies (
		TargetTypeID,
		TargetOUID,
		TargetID,
		PackagePathID,
		PolicyGUID,
		AllocationDetailsID,
		Precedence,
		PolicyVersion
	)
		SELECT	TargetTypeID,
			TargetOUID,
			TargetID,
			PackagePathID,
			PolicyGUID,
			AllocationDetailsID,
			Precedence,
			PolicyVersion
		FROM #PackageApplies
	SET @count = @@ROWCOUNT
	DROP TABLE #PackageApplies	-- Drop temporary table
	RETURN @count
GO

/*
Add new PackageApplies bound to
	AllocationDetails using Action, EffectiveFrom, EffectiveFromIsLocal, EffectiveUntil, Wake, PostponeNoLaterThan, PostponeNoLaterThanIsLocal, PostponePeriod, PostponeLatest, PostponeOKForLowBandwidth, PostponeOKForAnyReason, Exclusive, Removable
	Organization using DomainID, RDN
	TargetType using TargetTypeName
	with TargetID, PackagePathID, PolicyGUID, Precedence, PolicyVersion
*/

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[PackageAppliesUpdateByTargetOUIDTargetTypeIDTargetIDPackagePathIDPolicyGUID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[PackageAppliesUpdateByTargetOUIDTargetTypeIDTargetIDPackagePathIDPolicyGUID]
GO
CREATE PROCEDURE [dbo].[PackageAppliesUpdateByTargetOUIDTargetTypeIDTargetIDPackagePathIDPolicyGUID]
	@TargetOUID		int,
	@TargetTypeID		int,
	@TargetID		int,
	@PackagePathID		int,
	@PolicyGUID		binary(16),
	@AllocationDetailsID	int,
	@Precedence		int = 0,
	@PolicyVersion		int = 0
AS
	UPDATE	[dbo].[PackageApplies]
	SET	AllocationDetailsID = @AllocationDetailsID,
		Precedence = @Precedence,
		PolicyVersion = @PolicyVersion
	WHERE	TargetOUID = @TargetOUID
	  AND	TargetTypeID = @TargetTypeID
	  AND	TargetID = @TargetID
	  AND	PackagePathID = @PackagePathID
	  AND	PolicyGUID = @PolicyGUID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[PackageAppliesUpdateBatchByTargetOUIDTargetTypeIDTargetIDPackagePathIDPolicyGUID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[PackageAppliesUpdateBatchByTargetOUIDTargetTypeIDTargetIDPackagePathIDPolicyGUID]
GO
CREATE PROCEDURE dbo.[PackageAppliesUpdateBatchByTargetOUIDTargetTypeIDTargetIDPackagePathIDPolicyGUID]
AS
	DECLARE @count int

	CREATE INDEX [TempPackageAppliesTargetOUIDTargetTypeIDTargetIDPackagePathIDPolicyGUID]
		ON #PackageApplies (TargetOUID, TargetTypeID, TargetID, PackagePathID, PolicyGUID)

	UPDATE	[dbo].[PackageApplies]
	SET	AllocationDetailsID = t.AllocationDetailsID,
		Precedence = t.Precedence,
		PolicyVersion = t.PolicyVersion
	FROM	#PackageApplies AS t
	WHERE	PackageApplies.TargetOUID = t.TargetOUID
	  AND	PackageApplies.TargetTypeID = t.TargetTypeID
	  AND	PackageApplies.TargetID = t.TargetID
	  AND	PackageApplies.PackagePathID = t.PackagePathID
	  AND	PackageApplies.PolicyGUID = t.PolicyGUID
	SET @count = @@ROWCOUNT
	DROP TABLE #PackageApplies	-- Drop the temporary table
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[PackageAppliesPutByTargetOUIDTargetTypeIDTargetIDPackagePathIDPolicyGUID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[PackageAppliesPutByTargetOUIDTargetTypeIDTargetIDPackagePathIDPolicyGUID]
GO
CREATE PROCEDURE [dbo].[PackageAppliesPutByTargetOUIDTargetTypeIDTargetIDPackagePathIDPolicyGUID]
	@TargetOUID		int,
	@TargetTypeID		int,
	@TargetID		int,
	@PackagePathID		int,
	@PolicyGUID		binary(16),
	@AllocationDetailsID	int,
	@Precedence		int = 0,
	@PolicyVersion		int = 0
AS
	IF NOT EXISTS(
		SELECT	1
		FROM	dbo.PackageApplies
		WHERE	TargetOUID = @TargetOUID
		  AND	TargetTypeID = @TargetTypeID
		  AND	TargetID = @TargetID
		  AND	PackagePathID = @PackagePathID
		  AND	PolicyGUID = @PolicyGUID
	)
		EXEC PackageAppliesAdd @TargetTypeID,
			@TargetOUID,
			@TargetID,
			@PackagePathID,
			@PolicyGUID,
			@AllocationDetailsID,
			@Precedence,
			@PolicyVersion
	ELSE
		EXEC PackageAppliesUpdateByTargetOUIDTargetTypeIDTargetIDPackagePathIDPolicyGUID @TargetOUID,
			@TargetTypeID,
			@TargetID,
			@PackagePathID,
			@PolicyGUID,
			@AllocationDetailsID,
			@Precedence,
			@PolicyVersion
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[PackageAppliesPutBatchByTargetOUIDTargetTypeIDTargetIDPackagePathIDPolicyGUID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[PackageAppliesPutBatchByTargetOUIDTargetTypeIDTargetIDPackagePathIDPolicyGUID]
GO
CREATE PROCEDURE [dbo].[PackageAppliesPutBatchByTargetOUIDTargetTypeIDTargetIDPackagePathIDPolicyGUID]
AS
	DECLARE @count AS int
	SET @count = 0

	CREATE INDEX [TempPackageAppliesTargetOUIDTargetTypeIDTargetIDPackagePathIDPolicyGUID]
		ON #PackageApplies (TargetOUID, TargetTypeID, TargetID, PackagePathID, PolicyGUID)

	BEGIN TRANSACTION
	UPDATE [dbo].[PackageApplies]
		SET	AllocationDetailsID = t.AllocationDetailsID,
			Precedence = t.Precedence,
			PolicyVersion = t.PolicyVersion
		FROM	#PackageApplies AS t
		WHERE	PackageApplies.TargetOUID = t.TargetOUID
		  AND	PackageApplies.TargetTypeID = t.TargetTypeID
		  AND	PackageApplies.TargetID = t.TargetID
		  AND	PackageApplies.PackagePathID = t.PackagePathID
		  AND	PackageApplies.PolicyGUID = t.PolicyGUID
	SET @count = @@ROWCOUNT

	INSERT [dbo].[PackageApplies] (
		TargetTypeID,
		TargetOUID,
		TargetID,
		PackagePathID,
		PolicyGUID,
		AllocationDetailsID,
		Precedence,
		PolicyVersion
	)
		SELECT	TargetTypeID,
			TargetOUID,
			TargetID,
			PackagePathID,
			PolicyGUID,
			AllocationDetailsID,
			Precedence,
			PolicyVersion
		FROM	#PackageApplies AS t
		WHERE NOT EXISTS(	-- Current record doesn't exist
			SELECT * FROM [dbo].[PackageApplies]
			WHERE	PackageApplies.TargetOUID = t.TargetOUID
			  AND	PackageApplies.TargetTypeID = t.TargetTypeID
			  AND	PackageApplies.TargetID = t.TargetID
			  AND	PackageApplies.PackagePathID = t.PackagePathID
			  AND	PackageApplies.PolicyGUID = t.PolicyGUID
		)
	SET @count = @count + @@ROWCOUNT
	DROP TABLE #PackageApplies	-- Drop the temporary table
	COMMIT WORK
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[PackageAppliesRemoveBatch]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[PackageAppliesRemoveBatch]
GO

CREATE PROCEDURE [dbo].[PackageAppliesRemoveBatch]
AS

	CREATE INDEX [TempPackageAppliesPackageAppliesRemoveBatch]
		ON #PackageApplies (TargetOUID, TargetTypeID, TargetID, PackagePathID, PolicyGUID)	

	-- Delete records from PackageApplies identified by fields of [TempPackageAppliesPackageAppliesRemoveBatch]
	DELETE [dbo].[PackageApplies]
	WHERE EXISTS(
			SELECT * FROM #PackageApplies AS t
			WHERE	PackageApplies.TargetOUID = t.TargetOUID
			  AND	PackageApplies.TargetTypeID = t.TargetTypeID
			  AND	PackageApplies.TargetID = t.TargetID
			  AND	PackageApplies.PackagePathID = t.PackagePathID
			  AND	PackageApplies.PolicyGUID = t.PolicyGUID
		)
	DROP TABLE #PackageApplies      -- Drop the temporary table
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[PackageAppliesRemoveByTargetOUIDTargetTypeIDTargetIDPackagePathIDPolicyGUID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[PackageAppliesRemoveByTargetOUIDTargetTypeIDTargetIDPackagePathIDPolicyGUID]
GO
CREATE PROCEDURE [dbo].[PackageAppliesRemoveByTargetOUIDTargetTypeIDTargetIDPackagePathIDPolicyGUID]
	@TargetOUID		int,
	@TargetTypeID		int,
	@TargetID		int,
	@PackagePathID		int,
	@PolicyGUID		binary(16)
AS
	DELETE	[dbo].[PackageApplies]
	WHERE	TargetOUID = @TargetOUID
	  AND	TargetTypeID = @TargetTypeID
	  AND	TargetID = @TargetID
	  AND	PackagePathID = @PackagePathID
	  AND	PolicyGUID = @PolicyGUID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[PackageAppliesRemoveAllByTargetOUIDTargetTypeIDTargetIDPackagePathID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[PackageAppliesRemoveAllByTargetOUIDTargetTypeIDTargetIDPackagePathID]
GO
CREATE PROCEDURE [dbo].[PackageAppliesRemoveAllByTargetOUIDTargetTypeIDTargetIDPackagePathID]
	@TargetOUID		int,
	@TargetTypeID		int,
	@TargetID		int,
	@PackagePathID		int
AS
	DELETE	[dbo].[PackageApplies]
	WHERE	TargetOUID = @TargetOUID
	  AND	TargetTypeID = @TargetTypeID
	  AND	TargetID = @TargetID
	  AND	PackagePathID = @PackagePathID
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[PackageAppliesRemoveAll]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[PackageAppliesRemoveAll]
GO
CREATE PROCEDURE [dbo].[PackageAppliesRemoveAll]
	
AS
	DELETE	[dbo].[PackageApplies]
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[InstallationPostponementGetByTargetTypeIDTargetIDPackagePathIDPolicyGUID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[InstallationPostponementGetByTargetTypeIDTargetIDPackagePathIDPolicyGUID]
GO
CREATE PROCEDURE [dbo].[InstallationPostponementGetByTargetTypeIDTargetIDPackagePathIDPolicyGUID]
	@TargetTypeID		int,
	@TargetID		int,
	@PackagePathID		int,
	@PolicyGUID		binary(16)
AS
	SELECT	TargetTypeID,
		TargetID,
		PackagePathID,
		PolicyGUID,
		AllocationDetailsID,
		PostponePeriodStart
	FROM	[dbo].[InstallationPostponement]
	WHERE	TargetTypeID = @TargetTypeID
	  AND	TargetID = @TargetID
	  AND	PackagePathID = @PackagePathID
	  AND	PolicyGUID = @PolicyGUID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[InstallationPostponementGetAllByTargetTypeIDTargetIDPackagePathID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[InstallationPostponementGetAllByTargetTypeIDTargetIDPackagePathID]
GO
CREATE PROCEDURE [dbo].[InstallationPostponementGetAllByTargetTypeIDTargetIDPackagePathID]
	@TargetTypeID		int,
	@TargetID		int,
	@PackagePathID		int
AS
	SELECT	TargetTypeID,
		TargetID,
		PackagePathID,
		PolicyGUID,
		AllocationDetailsID,
		PostponePeriodStart
	FROM	[dbo].[InstallationPostponement]
	WHERE	TargetTypeID = @TargetTypeID
	  AND	TargetID = @TargetID
	  AND	PackagePathID = @PackagePathID
	ORDER BY PolicyGUID
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[InstallationPostponementGetAll]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[InstallationPostponementGetAll]
GO
CREATE PROCEDURE [dbo].[InstallationPostponementGetAll]
AS
	SELECT	TargetTypeID,
		TargetID,
		PackagePathID,
		PolicyGUID,
		AllocationDetailsID,
		PostponePeriodStart
	FROM	[dbo].[InstallationPostponement]
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[InstallationPostponementAdd]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[InstallationPostponementAdd]
GO
CREATE PROCEDURE [dbo].[InstallationPostponementAdd]
	@TargetTypeID		int,
	@TargetID		int,
	@PackagePathID		int,
	@PolicyGUID		binary(16),
	@AllocationDetailsID	int,
	@PostponePeriodStart	datetime = NULL
AS
	INSERT INTO  dbo.InstallationPostponement (
		TargetTypeID,
		TargetID,
		PackagePathID,
		PolicyGUID,
		AllocationDetailsID,
		PostponePeriodStart
	)
	VALUES (
		@TargetTypeID,
		@TargetID,
		@PackagePathID,
		@PolicyGUID,
		@AllocationDetailsID,
		@PostponePeriodStart
	)
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[InstallationPostponementSchema]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[InstallationPostponementSchema]
GO
CREATE PROCEDURE [dbo].[InstallationPostponementSchema]
AS
	SELECT
	'IF OBJECT_ID(''tempdb..#InstallationPostponement'') IS NULL' + CAST(0x0A AS CHAR(1)) +
	'	CREATE TABLE #InstallationPostponement (' + CAST(0x0A AS CHAR(1)) +
	'		TargetTypeID		int NOT NULL,' + CAST(0x0A AS CHAR(1)) +
	'		TargetID		int NOT NULL,' + CAST(0x0A AS CHAR(1)) +
	'		PackagePathID		int NOT NULL,' + CAST(0x0A AS CHAR(1)) +
	'		PolicyGUID		binary(16) NOT NULL,' + CAST(0x0A AS CHAR(1)) +
	'		AllocationDetailsID	int NOT NULL,' + CAST(0x0A AS CHAR(1)) +
	'		PostponePeriodStart	datetime NULL' + CAST(0x0A AS CHAR(1)) +
	'	)' + CAST(0x0A AS CHAR(1)) +
	'ELSE' + CAST(0x0A AS CHAR(1)) +
	'	DELETE FROM #InstallationPostponement' + CAST(0x0A AS CHAR(1)) +
	'' AS SQL
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[InstallationPostponementTempAdd]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[InstallationPostponementTempAdd]
GO
CREATE PROCEDURE dbo.[InstallationPostponementTempAdd]
	@TargetTypeID		int,
	@TargetID		int,
	@PackagePathID		int,
	@PolicyGUID		binary(16),
	@AllocationDetailsID	int,
	@PostponePeriodStart	datetime = NULL
AS
	INSERT INTO #InstallationPostponement (
		TargetTypeID,
		TargetID,
		PackagePathID,
		PolicyGUID,
		AllocationDetailsID,
		PostponePeriodStart
	)
	VALUES (
		@TargetTypeID,
		@TargetID,
		@PackagePathID,
		@PolicyGUID,
		@AllocationDetailsID,
		@PostponePeriodStart
	)
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[InstallationPostponementAddBatch]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[InstallationPostponementAddBatch]
GO
CREATE PROCEDURE dbo.[InstallationPostponementAddBatch]
AS
	DECLARE @count int
	INSERT dbo.InstallationPostponement (
		TargetTypeID,
		TargetID,
		PackagePathID,
		PolicyGUID,
		AllocationDetailsID,
		PostponePeriodStart
	)
		SELECT	TargetTypeID,
			TargetID,
			PackagePathID,
			PolicyGUID,
			AllocationDetailsID,
			PostponePeriodStart
		FROM #InstallationPostponement
	SET @count = @@ROWCOUNT
	DROP TABLE #InstallationPostponement	-- Drop temporary table
	RETURN @count
GO

/*
Add new InstallationPostponement bound to
	TargetType using TargetTypeName
	AllocationDetails using Action, EffectiveFrom, EffectiveFromIsLocal, EffectiveUntil, Wake, PostponeNoLaterThan, PostponeNoLaterThanIsLocal, PostponePeriod, PostponeLatest, PostponeOKForLowBandwidth, PostponeOKForAnyReason, Exclusive, Removable
	with TargetID, PackagePathID, PolicyGUID, PostponePeriodStart
*/

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[InstallationPostponementUpdateByTargetTypeIDTargetIDPackagePathIDPolicyGUID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[InstallationPostponementUpdateByTargetTypeIDTargetIDPackagePathIDPolicyGUID]
GO
CREATE PROCEDURE [dbo].[InstallationPostponementUpdateByTargetTypeIDTargetIDPackagePathIDPolicyGUID]
	@TargetTypeID		int,
	@TargetID		int,
	@PackagePathID		int,
	@PolicyGUID		binary(16),
	@AllocationDetailsID	int,
	@PostponePeriodStart	datetime = NULL
AS
	UPDATE	[dbo].[InstallationPostponement]
	SET	AllocationDetailsID = @AllocationDetailsID,
		PostponePeriodStart = @PostponePeriodStart
	WHERE	TargetTypeID = @TargetTypeID
	  AND	TargetID = @TargetID
	  AND	PackagePathID = @PackagePathID
	  AND	PolicyGUID = @PolicyGUID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[InstallationPostponementUpdateBatchByTargetTypeIDTargetIDPackagePathIDPolicyGUID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[InstallationPostponementUpdateBatchByTargetTypeIDTargetIDPackagePathIDPolicyGUID]
GO
CREATE PROCEDURE dbo.[InstallationPostponementUpdateBatchByTargetTypeIDTargetIDPackagePathIDPolicyGUID]
AS
	DECLARE @count int

	CREATE INDEX [TempInstallationPostponementTargetTypeIDTargetIDPackagePathIDPolicyGUID]
		ON #InstallationPostponement (TargetTypeID, TargetID, PackagePathID, PolicyGUID)

	UPDATE	[dbo].[InstallationPostponement]
	SET	AllocationDetailsID = t.AllocationDetailsID,
		PostponePeriodStart = t.PostponePeriodStart
	FROM	#InstallationPostponement AS t
	WHERE	InstallationPostponement.TargetTypeID = t.TargetTypeID
	  AND	InstallationPostponement.TargetID = t.TargetID
	  AND	InstallationPostponement.PackagePathID = t.PackagePathID
	  AND	InstallationPostponement.PolicyGUID = t.PolicyGUID
	SET @count = @@ROWCOUNT
	DROP TABLE #InstallationPostponement	-- Drop the temporary table
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[InstallationPostponementPutByTargetTypeIDTargetIDPackagePathIDPolicyGUID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[InstallationPostponementPutByTargetTypeIDTargetIDPackagePathIDPolicyGUID]
GO
CREATE PROCEDURE [dbo].[InstallationPostponementPutByTargetTypeIDTargetIDPackagePathIDPolicyGUID]
	@TargetTypeID		int,
	@TargetID		int,
	@PackagePathID		int,
	@PolicyGUID		binary(16),
	@AllocationDetailsID	int,
	@PostponePeriodStart	datetime = NULL
AS
	IF NOT EXISTS(
		SELECT	1
		FROM	dbo.InstallationPostponement
		WHERE	TargetTypeID = @TargetTypeID
		  AND	TargetID = @TargetID
		  AND	PackagePathID = @PackagePathID
		  AND	PolicyGUID = @PolicyGUID
	)
		EXEC InstallationPostponementAdd @TargetTypeID,
			@TargetID,
			@PackagePathID,
			@PolicyGUID,
			@AllocationDetailsID,
			@PostponePeriodStart
	ELSE
		EXEC InstallationPostponementUpdateByTargetTypeIDTargetIDPackagePathIDPolicyGUID @TargetTypeID,
			@TargetID,
			@PackagePathID,
			@PolicyGUID,
			@AllocationDetailsID,
			@PostponePeriodStart
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[InstallationPostponementPutBatchByTargetTypeIDTargetIDPackagePathIDPolicyGUID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[InstallationPostponementPutBatchByTargetTypeIDTargetIDPackagePathIDPolicyGUID]
GO
CREATE PROCEDURE [dbo].[InstallationPostponementPutBatchByTargetTypeIDTargetIDPackagePathIDPolicyGUID]
AS
	DECLARE @count AS int
	SET @count = 0

	CREATE INDEX [TempInstallationPostponementTargetTypeIDTargetIDPackagePathIDPolicyGUID]
		ON #InstallationPostponement (TargetTypeID, TargetID, PackagePathID, PolicyGUID)

	BEGIN TRANSACTION
	UPDATE [dbo].[InstallationPostponement]
		SET	AllocationDetailsID = t.AllocationDetailsID,
			PostponePeriodStart = t.PostponePeriodStart
		FROM	#InstallationPostponement AS t
		WHERE	InstallationPostponement.TargetTypeID = t.TargetTypeID
		  AND	InstallationPostponement.TargetID = t.TargetID
		  AND	InstallationPostponement.PackagePathID = t.PackagePathID
		  AND	InstallationPostponement.PolicyGUID = t.PolicyGUID
	SET @count = @@ROWCOUNT

	INSERT [dbo].[InstallationPostponement] (
		TargetTypeID,
		TargetID,
		PackagePathID,
		PolicyGUID,
		AllocationDetailsID,
		PostponePeriodStart
	)
		SELECT	TargetTypeID,
			TargetID,
			PackagePathID,
			PolicyGUID,
			AllocationDetailsID,
			PostponePeriodStart
		FROM	#InstallationPostponement AS t
		WHERE NOT EXISTS(	-- Current record doesn't exist
			SELECT * FROM [dbo].[InstallationPostponement]
			WHERE	InstallationPostponement.TargetTypeID = t.TargetTypeID
			  AND	InstallationPostponement.TargetID = t.TargetID
			  AND	InstallationPostponement.PackagePathID = t.PackagePathID
			  AND	InstallationPostponement.PolicyGUID = t.PolicyGUID
		)
	SET @count = @count + @@ROWCOUNT
	DROP TABLE #InstallationPostponement	-- Drop the temporary table
	COMMIT WORK
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[InstallationPostponementRemoveBatch]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[InstallationPostponementRemoveBatch]
GO

CREATE PROCEDURE [dbo].[InstallationPostponementRemoveBatch]
AS

	CREATE INDEX [TempInstallationPostponementInstallationPostponementRemoveBatch]
		ON #InstallationPostponement (TargetTypeID, TargetID, PackagePathID, PolicyGUID)	

	-- Delete records from InstallationPostponement identified by fields of [TempInstallationPostponementInstallationPostponementRemoveBatch]
	DELETE [dbo].[InstallationPostponement]
	WHERE EXISTS(
			SELECT * FROM #InstallationPostponement AS t
			WHERE	InstallationPostponement.TargetTypeID = t.TargetTypeID
			  AND	InstallationPostponement.TargetID = t.TargetID
			  AND	InstallationPostponement.PackagePathID = t.PackagePathID
			  AND	InstallationPostponement.PolicyGUID = t.PolicyGUID
		)
	DROP TABLE #InstallationPostponement      -- Drop the temporary table
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[InstallationPostponementRemoveByTargetTypeIDTargetIDPackagePathIDPolicyGUID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[InstallationPostponementRemoveByTargetTypeIDTargetIDPackagePathIDPolicyGUID]
GO
CREATE PROCEDURE [dbo].[InstallationPostponementRemoveByTargetTypeIDTargetIDPackagePathIDPolicyGUID]
	@TargetTypeID		int,
	@TargetID		int,
	@PackagePathID		int,
	@PolicyGUID		binary(16)
AS
	DELETE	[dbo].[InstallationPostponement]
	WHERE	TargetTypeID = @TargetTypeID
	  AND	TargetID = @TargetID
	  AND	PackagePathID = @PackagePathID
	  AND	PolicyGUID = @PolicyGUID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[InstallationPostponementRemoveAllByTargetTypeIDTargetIDPackagePathID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[InstallationPostponementRemoveAllByTargetTypeIDTargetIDPackagePathID]
GO
CREATE PROCEDURE [dbo].[InstallationPostponementRemoveAllByTargetTypeIDTargetIDPackagePathID]
	@TargetTypeID		int,
	@TargetID		int,
	@PackagePathID		int
AS
	DELETE	[dbo].[InstallationPostponement]
	WHERE	TargetTypeID = @TargetTypeID
	  AND	TargetID = @TargetID
	  AND	PackagePathID = @PackagePathID
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[InstallationPostponementRemoveAll]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[InstallationPostponementRemoveAll]
GO
CREATE PROCEDURE [dbo].[InstallationPostponementRemoveAll]
	
AS
	DELETE	[dbo].[InstallationPostponement]
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[DeviceRoleGetByID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[DeviceRoleGetByID]
GO
CREATE PROCEDURE [dbo].[DeviceRoleGetByID]
	@DeviceRoleID		int
AS
	SELECT	DeviceRoleID,
		Description
	FROM	[dbo].[DeviceRole]
	WHERE	DeviceRoleID = @DeviceRoleID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[DeviceRoleGetByDescription]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[DeviceRoleGetByDescription]
GO
CREATE PROCEDURE [dbo].[DeviceRoleGetByDescription]
	@Description		nvarchar(64)
AS
	SELECT	DeviceRoleID,
		Description
	FROM	[dbo].[DeviceRole]
	WHERE	Description = @Description
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[DeviceRoleGetAll]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[DeviceRoleGetAll]
GO
CREATE PROCEDURE [dbo].[DeviceRoleGetAll]
AS
	SELECT	DeviceRoleID,
		Description
	FROM	[dbo].[DeviceRole]
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[DeviceRoleBind]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[DeviceRoleBind]
GO
CREATE PROCEDURE [dbo].[DeviceRoleBind]
	@Description		nvarchar(64)
AS
	DECLARE	@ID	int

	SELECT	@ID = DeviceRoleID
	FROM	[dbo].[DeviceRole]
	WHERE	Description = @Description

	RETURN @ID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ASN1ObjectGetByOID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ASN1ObjectGetByOID]
GO
CREATE PROCEDURE [dbo].[ASN1ObjectGetByOID]
	@OID			nvarchar(128)
AS
	SELECT	OID,
		Description,
		ObjectRole
	FROM	[dbo].[ASN1Object]
	WHERE	OID = @OID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ASN1ObjectGetAll]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ASN1ObjectGetAll]
GO
CREATE PROCEDURE [dbo].[ASN1ObjectGetAll]
AS
	SELECT	OID,
		Description,
		ObjectRole
	FROM	[dbo].[ASN1Object]
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ASN1ObjectAdd]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ASN1ObjectAdd]
GO
CREATE PROCEDURE [dbo].[ASN1ObjectAdd]
	@OID			nvarchar(128),
	@Description		nvarchar(512),
	@ObjectRole		int = NULL
AS
	INSERT INTO  dbo.ASN1Object (
		OID,
		Description,
		ObjectRole
	)
	VALUES (
		@OID,
		@Description,
		@ObjectRole
	)
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ASN1ObjectSchema]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ASN1ObjectSchema]
GO
CREATE PROCEDURE [dbo].[ASN1ObjectSchema]
AS
	SELECT
	'IF OBJECT_ID(''tempdb..#ASN1Object'') IS NULL' + CAST(0x0A AS CHAR(1)) +
	'	CREATE TABLE #ASN1Object (' + CAST(0x0A AS CHAR(1)) +
	'		OID			nvarchar(128) COLLATE database_default NOT NULL,' + CAST(0x0A AS CHAR(1)) +
	'		Description		nvarchar(512) COLLATE database_default NOT NULL,' + CAST(0x0A AS CHAR(1)) +
	'		ObjectRole		int NULL' + CAST(0x0A AS CHAR(1)) +
	'	)' + CAST(0x0A AS CHAR(1)) +
	'ELSE' + CAST(0x0A AS CHAR(1)) +
	'	DELETE FROM #ASN1Object' + CAST(0x0A AS CHAR(1)) +
	'' AS SQL
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ASN1ObjectTempAdd]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ASN1ObjectTempAdd]
GO
CREATE PROCEDURE dbo.[ASN1ObjectTempAdd]
	@OID			nvarchar(128),
	@Description		nvarchar(512),
	@ObjectRole		int = NULL
AS
	INSERT INTO #ASN1Object (
		OID,
		Description,
		ObjectRole
	)
	VALUES (
		@OID,
		@Description,
		@ObjectRole
	)
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ASN1ObjectAddBatch]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ASN1ObjectAddBatch]
GO
CREATE PROCEDURE dbo.[ASN1ObjectAddBatch]
AS
	DECLARE @count int
	INSERT dbo.ASN1Object (
		OID,
		Description,
		ObjectRole
	)
		SELECT	OID,
			Description,
			ObjectRole
		FROM #ASN1Object
	SET @count = @@ROWCOUNT
	DROP TABLE #ASN1Object	-- Drop temporary table
	RETURN @count
GO

/*
Add new ASN1Object bound to
	DeviceRole using Description
	with OID, Description
*/

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ASN1ObjectUpdateByOID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ASN1ObjectUpdateByOID]
GO
CREATE PROCEDURE [dbo].[ASN1ObjectUpdateByOID]
	@OID			nvarchar(128),
	@Description		nvarchar(512),
	@ObjectRole		int = NULL
AS
	UPDATE	[dbo].[ASN1Object]
	SET	Description = @Description,
		ObjectRole = @ObjectRole
	WHERE	OID = @OID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ASN1ObjectUpdateBatchByOID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ASN1ObjectUpdateBatchByOID]
GO
CREATE PROCEDURE dbo.[ASN1ObjectUpdateBatchByOID]
AS
	DECLARE @count int

	CREATE INDEX [TempASN1ObjectOID]
		ON #ASN1Object (OID)

	UPDATE	[dbo].[ASN1Object]
	SET	Description = t.Description,
		ObjectRole = t.ObjectRole
	FROM	#ASN1Object AS t
	WHERE	ASN1Object.OID = t.OID
	SET @count = @@ROWCOUNT
	DROP TABLE #ASN1Object	-- Drop the temporary table
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ASN1ObjectPutByOID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ASN1ObjectPutByOID]
GO
CREATE PROCEDURE [dbo].[ASN1ObjectPutByOID]
	@OID			nvarchar(128),
	@Description		nvarchar(512),
	@ObjectRole		int = NULL
AS
	IF NOT EXISTS(
		SELECT	1
		FROM	dbo.ASN1Object
		WHERE	OID = @OID
	)
		EXEC ASN1ObjectAdd @OID,
			@Description,
			@ObjectRole
	ELSE
		EXEC ASN1ObjectUpdateByOID @OID,
			@Description,
			@ObjectRole
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ASN1ObjectPutBatchByOID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ASN1ObjectPutBatchByOID]
GO
CREATE PROCEDURE [dbo].[ASN1ObjectPutBatchByOID]
AS
	DECLARE @count AS int
	SET @count = 0

	CREATE INDEX [TempASN1ObjectOID]
		ON #ASN1Object (OID)

	BEGIN TRANSACTION
	UPDATE [dbo].[ASN1Object]
		SET	Description = t.Description,
			ObjectRole = t.ObjectRole
		FROM	#ASN1Object AS t
		WHERE	ASN1Object.OID = t.OID
	SET @count = @@ROWCOUNT

	INSERT [dbo].[ASN1Object] (
		OID,
		Description,
		ObjectRole
	)
		SELECT	OID,
			Description,
			ObjectRole
		FROM	#ASN1Object AS t
		WHERE NOT EXISTS(	-- Current record doesn't exist
			SELECT * FROM [dbo].[ASN1Object]
			WHERE	ASN1Object.OID = t.OID
		)
	SET @count = @count + @@ROWCOUNT
	DROP TABLE #ASN1Object	-- Drop the temporary table
	COMMIT WORK
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ASN1ObjectRemoveBatch]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ASN1ObjectRemoveBatch]
GO

CREATE PROCEDURE [dbo].[ASN1ObjectRemoveBatch]
AS

	CREATE INDEX [TempASN1ObjectASN1ObjectRemoveBatch]
		ON #ASN1Object (OID)	

	-- Delete records from ASN1Object identified by fields of [TempASN1ObjectASN1ObjectRemoveBatch]
	DELETE [dbo].[ASN1Object]
	WHERE EXISTS(
			SELECT * FROM #ASN1Object AS t
			WHERE	ASN1Object.OID = t.OID
		)
	DROP TABLE #ASN1Object      -- Drop the temporary table
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ASN1ObjectRemoveByOID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ASN1ObjectRemoveByOID]
GO
CREATE PROCEDURE [dbo].[ASN1ObjectRemoveByOID]
	@OID			nvarchar(128)
AS
	DELETE	[dbo].[ASN1Object]
	WHERE	OID = @OID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ASN1ObjectRemoveAll]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ASN1ObjectRemoveAll]
GO
CREATE PROCEDURE [dbo].[ASN1ObjectRemoveAll]
	
AS
	DELETE	[dbo].[ASN1Object]
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[NetworkDeviceGetByID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[NetworkDeviceGetByID]
GO
CREATE PROCEDURE [dbo].[NetworkDeviceGetByID]
	@DeviceID		int
AS
	SELECT	DeviceID,
		DuplicateID,
		ComputerID,
		DeviceName,
		DNSFullName,
		NTDomainName,
		IPAddress,
		IPSubnet,
		IPSubnetMask,
		PhysicalAddress,
		DeviceRole,
		OperatingSystem,
		OperatingSystemID,
		IsManaged,
		Description,
		SystemDescription,
		SystemLocation,
		SystemContact,
		FirstDiscovered,
		LastUpdate,
		LastDataSourceName,
		LastDataSourceType,
		OpenPortsTCP,
		OpenPortsUDP,
		ScannedOperatingSystem,
		ScannedOsType,
		ScannedOsVendor,
		ScannedOsFamily,
		ScannedOsGen,
		ScannedMacAddress,
		ScannedMacVendor,
		SQLDiscoveredBy,
		SQLPorts
	FROM	[dbo].[NetworkDevice]
	WHERE	DeviceID = @DeviceID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[NetworkDeviceGetAllByNTDomainName]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[NetworkDeviceGetAllByNTDomainName]
GO
CREATE PROCEDURE [dbo].[NetworkDeviceGetAllByNTDomainName]
	@NTDomainName		nvarchar(256) = NULL
AS
	SELECT	DeviceID,
		DuplicateID,
		ComputerID,
		DeviceName,
		DNSFullName,
		NTDomainName,
		IPAddress,
		IPSubnet,
		IPSubnetMask,
		PhysicalAddress,
		DeviceRole,
		OperatingSystem,
		OperatingSystemID,
		IsManaged,
		Description,
		SystemDescription,
		SystemLocation,
		SystemContact,
		FirstDiscovered,
		LastUpdate,
		LastDataSourceName,
		LastDataSourceType,
		OpenPortsTCP,
		OpenPortsUDP,
		ScannedOperatingSystem,
		ScannedOsType,
		ScannedOsVendor,
		ScannedOsFamily,
		ScannedOsGen,
		ScannedMacAddress,
		ScannedMacVendor,
		SQLDiscoveredBy,
		SQLPorts
	FROM	[dbo].[NetworkDevice]
	WHERE	(NTDomainName = @NTDomainName OR (NTDomainName IS NULL AND @NTDomainName IS NULL))
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[NetworkDeviceGetAll]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[NetworkDeviceGetAll]
GO
CREATE PROCEDURE [dbo].[NetworkDeviceGetAll]
AS
	SELECT	DeviceID,
		DuplicateID,
		ComputerID,
		DeviceName,
		DNSFullName,
		NTDomainName,
		IPAddress,
		IPSubnet,
		IPSubnetMask,
		PhysicalAddress,
		DeviceRole,
		OperatingSystem,
		OperatingSystemID,
		IsManaged,
		Description,
		SystemDescription,
		SystemLocation,
		SystemContact,
		FirstDiscovered,
		LastUpdate,
		LastDataSourceName,
		LastDataSourceType,
		OpenPortsTCP,
		OpenPortsUDP,
		ScannedOperatingSystem,
		ScannedOsType,
		ScannedOsVendor,
		ScannedOsFamily,
		ScannedOsGen,
		ScannedMacAddress,
		ScannedMacVendor,
		SQLDiscoveredBy,
		SQLPorts
	FROM	[dbo].[NetworkDevice]
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[NetworkDeviceAdd]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[NetworkDeviceAdd]
GO
CREATE PROCEDURE [dbo].[NetworkDeviceAdd]
	@DuplicateID		int = NULL,
	@ComputerID		int = NULL,
	@DeviceName		nvarchar(64) = NULL,
	@DNSFullName		nvarchar(256) = NULL,
	@NTDomainName		nvarchar(256) = NULL,
	@IPAddress		varchar(64) = NULL,
	@IPSubnet		varchar(64) = NULL,
	@IPSubnetMask		varchar(64) = NULL,
	@PhysicalAddress	varchar(64) = NULL,
	@DeviceRole		int = NULL,
	@OperatingSystem	nvarchar(128) = NULL,
	@OperatingSystemID	int = NULL,
	@IsManaged		int = NULL,
	@Description		nvarchar(256) = NULL,
	@SystemDescription	nvarchar(256) = NULL,
	@SystemLocation		nvarchar(256) = NULL,
	@SystemContact		nvarchar(256) = NULL,
	@FirstDiscovered	datetime,
	@LastUpdate		datetime,
	@LastDataSourceName	nvarchar(128) = NULL,
	@LastDataSourceType	nvarchar(32) = NULL,
	@OpenPortsTCP		varchar(512) = NULL,
	@OpenPortsUDP		varchar(512) = NULL,
	@ScannedOperatingSystem	nvarchar(512) = NULL,
	@ScannedOsType		nvarchar(512) = NULL,
	@ScannedOsVendor	nvarchar(512) = NULL,
	@ScannedOsFamily	nvarchar(512) = NULL,
	@ScannedOsGen		nvarchar(512) = NULL,
	@ScannedMacAddress	varchar(64) = NULL,
	@ScannedMacVendor	nvarchar(512) = NULL,
	@SQLDiscoveredBy	nvarchar(128) = NULL,
	@SQLPorts		nvarchar(128) = NULL
AS
	INSERT INTO  dbo.NetworkDevice (
		DuplicateID,
		ComputerID,
		DeviceName,
		DNSFullName,
		NTDomainName,
		IPAddress,
		IPSubnet,
		IPSubnetMask,
		PhysicalAddress,
		DeviceRole,
		OperatingSystem,
		OperatingSystemID,
		IsManaged,
		Description,
		SystemDescription,
		SystemLocation,
		SystemContact,
		FirstDiscovered,
		LastUpdate,
		LastDataSourceName,
		LastDataSourceType,
		OpenPortsTCP,
		OpenPortsUDP,
		ScannedOperatingSystem,
		ScannedOsType,
		ScannedOsVendor,
		ScannedOsFamily,
		ScannedOsGen,
		ScannedMacAddress,
		ScannedMacVendor,
		SQLDiscoveredBy,
		SQLPorts
	)
	VALUES (
		@DuplicateID,
		@ComputerID,
		@DeviceName,
		@DNSFullName,
		@NTDomainName,
		@IPAddress,
		@IPSubnet,
		@IPSubnetMask,
		@PhysicalAddress,
		@DeviceRole,
		@OperatingSystem,
		@OperatingSystemID,
		@IsManaged,
		@Description,
		@SystemDescription,
		@SystemLocation,
		@SystemContact,
		@FirstDiscovered,
		@LastUpdate,
		@LastDataSourceName,
		@LastDataSourceType,
		@OpenPortsTCP,
		@OpenPortsUDP,
		@ScannedOperatingSystem,
		@ScannedOsType,
		@ScannedOsVendor,
		@ScannedOsFamily,
		@ScannedOsGen,
		@ScannedMacAddress,
		@ScannedMacVendor,
		@SQLDiscoveredBy,
		@SQLPorts
	)
	RETURN SCOPE_IDENTITY()
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[NetworkDeviceSchema]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[NetworkDeviceSchema]
GO
CREATE PROCEDURE [dbo].[NetworkDeviceSchema]
AS
	SELECT
	'IF OBJECT_ID(''tempdb..#NetworkDevice'') IS NULL' + CAST(0x0A AS CHAR(1)) +
	'	CREATE TABLE #NetworkDevice (' + CAST(0x0A AS CHAR(1)) +
	'		DeviceID		int NULL,' + CAST(0x0A AS CHAR(1)) +
	'		DuplicateID		int NULL,' + CAST(0x0A AS CHAR(1)) +
	'		ComputerID		int NULL,' + CAST(0x0A AS CHAR(1)) +
	'		DeviceName		nvarchar(64) COLLATE database_default NULL,' + CAST(0x0A AS CHAR(1)) +
	'		DNSFullName		nvarchar(256) COLLATE database_default NULL,' + CAST(0x0A AS CHAR(1)) +
	'		NTDomainName		nvarchar(256) COLLATE database_default NULL,' + CAST(0x0A AS CHAR(1)) +
	'		IPAddress		varchar(64) COLLATE database_default NULL,' + CAST(0x0A AS CHAR(1)) +
	'		IPSubnet		varchar(64) COLLATE database_default NULL,' + CAST(0x0A AS CHAR(1)) +
	'		IPSubnetMask		varchar(64) COLLATE database_default NULL,' + CAST(0x0A AS CHAR(1)) +
	'		PhysicalAddress		varchar(64) COLLATE database_default NULL,' + CAST(0x0A AS CHAR(1)) +
	'		DeviceRole		int NULL,' + CAST(0x0A AS CHAR(1)) +
	'		OperatingSystem		nvarchar(128) COLLATE database_default NULL,' + CAST(0x0A AS CHAR(1)) +
	'		OperatingSystemID	int NULL,' + CAST(0x0A AS CHAR(1)) +
	'		IsManaged		int NULL,' + CAST(0x0A AS CHAR(1)) +
	'		Description		nvarchar(256) COLLATE database_default NULL,' + CAST(0x0A AS CHAR(1)) +
	'		SystemDescription	nvarchar(256) COLLATE database_default NULL,' + CAST(0x0A AS CHAR(1)) +
	'		SystemLocation		nvarchar(256) COLLATE database_default NULL,' + CAST(0x0A AS CHAR(1)) +
	'		SystemContact		nvarchar(256) COLLATE database_default NULL,' + CAST(0x0A AS CHAR(1)) +
	'		FirstDiscovered		datetime NOT NULL DEFAULT getdate(),' + CAST(0x0A AS CHAR(1)) +
	'		LastUpdate		datetime NOT NULL DEFAULT getdate(),' + CAST(0x0A AS CHAR(1)) +
	'		LastDataSourceName	nvarchar(128) COLLATE database_default NULL,' + CAST(0x0A AS CHAR(1)) +
	'		LastDataSourceType	nvarchar(32) COLLATE database_default NULL,' + CAST(0x0A AS CHAR(1)) +
	'		OpenPortsTCP		varchar(512) COLLATE database_default NULL,' + CAST(0x0A AS CHAR(1)) +
	'		OpenPortsUDP		varchar(512) COLLATE database_default NULL,' + CAST(0x0A AS CHAR(1)) +
	'		ScannedOperatingSystem	nvarchar(512) COLLATE database_default NULL,' + CAST(0x0A AS CHAR(1)) +
	'		ScannedOsType		nvarchar(512) COLLATE database_default NULL,' + CAST(0x0A AS CHAR(1)) +
	'		ScannedOsVendor		nvarchar(512) COLLATE database_default NULL,' + CAST(0x0A AS CHAR(1)) +
	'		ScannedOsFamily		nvarchar(512) COLLATE database_default NULL,' + CAST(0x0A AS CHAR(1)) +
	'		ScannedOsGen		nvarchar(512) COLLATE database_default NULL,' + CAST(0x0A AS CHAR(1)) +
	'		ScannedMacAddress	varchar(64) COLLATE database_default NULL,' + CAST(0x0A AS CHAR(1)) +
	'		ScannedMacVendor	nvarchar(512) COLLATE database_default NULL,' + CAST(0x0A AS CHAR(1)) +
	'		SQLDiscoveredBy		nvarchar(128) COLLATE database_default NULL,' + CAST(0x0A AS CHAR(1)) +
	'		SQLPorts		nvarchar(128) COLLATE database_default NULL' + CAST(0x0A AS CHAR(1)) +
	'	)' + CAST(0x0A AS CHAR(1)) +
	'ELSE' + CAST(0x0A AS CHAR(1)) +
	'	DELETE FROM #NetworkDevice' + CAST(0x0A AS CHAR(1)) +
	'' AS SQL
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[NetworkDeviceTempAdd]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[NetworkDeviceTempAdd]
GO
CREATE PROCEDURE dbo.[NetworkDeviceTempAdd]
	@DeviceID		int,
	@DuplicateID		int = NULL,
	@ComputerID		int = NULL,
	@DeviceName		nvarchar(64) = NULL,
	@DNSFullName		nvarchar(256) = NULL,
	@NTDomainName		nvarchar(256) = NULL,
	@IPAddress		varchar(64) = NULL,
	@IPSubnet		varchar(64) = NULL,
	@IPSubnetMask		varchar(64) = NULL,
	@PhysicalAddress	varchar(64) = NULL,
	@DeviceRole		int = NULL,
	@OperatingSystem	nvarchar(128) = NULL,
	@OperatingSystemID	int = NULL,
	@IsManaged		int = NULL,
	@Description		nvarchar(256) = NULL,
	@SystemDescription	nvarchar(256) = NULL,
	@SystemLocation		nvarchar(256) = NULL,
	@SystemContact		nvarchar(256) = NULL,
	@FirstDiscovered	datetime,
	@LastUpdate		datetime,
	@LastDataSourceName	nvarchar(128) = NULL,
	@LastDataSourceType	nvarchar(32) = NULL,
	@OpenPortsTCP		varchar(512) = NULL,
	@OpenPortsUDP		varchar(512) = NULL,
	@ScannedOperatingSystem	nvarchar(512) = NULL,
	@ScannedOsType		nvarchar(512) = NULL,
	@ScannedOsVendor	nvarchar(512) = NULL,
	@ScannedOsFamily	nvarchar(512) = NULL,
	@ScannedOsGen		nvarchar(512) = NULL,
	@ScannedMacAddress	varchar(64) = NULL,
	@ScannedMacVendor	nvarchar(512) = NULL,
	@SQLDiscoveredBy	nvarchar(128) = NULL,
	@SQLPorts		nvarchar(128) = NULL
AS
	INSERT INTO #NetworkDevice (
		DeviceID,
		DuplicateID,
		ComputerID,
		DeviceName,
		DNSFullName,
		NTDomainName,
		IPAddress,
		IPSubnet,
		IPSubnetMask,
		PhysicalAddress,
		DeviceRole,
		OperatingSystem,
		OperatingSystemID,
		IsManaged,
		Description,
		SystemDescription,
		SystemLocation,
		SystemContact,
		FirstDiscovered,
		LastUpdate,
		LastDataSourceName,
		LastDataSourceType,
		OpenPortsTCP,
		OpenPortsUDP,
		ScannedOperatingSystem,
		ScannedOsType,
		ScannedOsVendor,
		ScannedOsFamily,
		ScannedOsGen,
		ScannedMacAddress,
		ScannedMacVendor,
		SQLDiscoveredBy,
		SQLPorts
	)
	VALUES (
		@DeviceID,
		@DuplicateID,
		@ComputerID,
		@DeviceName,
		@DNSFullName,
		@NTDomainName,
		@IPAddress,
		@IPSubnet,
		@IPSubnetMask,
		@PhysicalAddress,
		@DeviceRole,
		@OperatingSystem,
		@OperatingSystemID,
		@IsManaged,
		@Description,
		@SystemDescription,
		@SystemLocation,
		@SystemContact,
		@FirstDiscovered,
		@LastUpdate,
		@LastDataSourceName,
		@LastDataSourceType,
		@OpenPortsTCP,
		@OpenPortsUDP,
		@ScannedOperatingSystem,
		@ScannedOsType,
		@ScannedOsVendor,
		@ScannedOsFamily,
		@ScannedOsGen,
		@ScannedMacAddress,
		@ScannedMacVendor,
		@SQLDiscoveredBy,
		@SQLPorts
	)
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[NetworkDeviceAddBatch]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[NetworkDeviceAddBatch]
GO
CREATE PROCEDURE dbo.[NetworkDeviceAddBatch]
AS
	DECLARE @count int
	INSERT dbo.NetworkDevice (
		DuplicateID,
		ComputerID,
		DeviceName,
		DNSFullName,
		NTDomainName,
		IPAddress,
		IPSubnet,
		IPSubnetMask,
		PhysicalAddress,
		DeviceRole,
		OperatingSystem,
		OperatingSystemID,
		IsManaged,
		Description,
		SystemDescription,
		SystemLocation,
		SystemContact,
		FirstDiscovered,
		LastUpdate,
		LastDataSourceName,
		LastDataSourceType,
		OpenPortsTCP,
		OpenPortsUDP,
		ScannedOperatingSystem,
		ScannedOsType,
		ScannedOsVendor,
		ScannedOsFamily,
		ScannedOsGen,
		ScannedMacAddress,
		ScannedMacVendor,
		SQLDiscoveredBy,
		SQLPorts
	)
		SELECT	DuplicateID,
			ComputerID,
			DeviceName,
			DNSFullName,
			NTDomainName,
			IPAddress,
			IPSubnet,
			IPSubnetMask,
			PhysicalAddress,
			DeviceRole,
			OperatingSystem,
			OperatingSystemID,
			IsManaged,
			Description,
			SystemDescription,
			SystemLocation,
			SystemContact,
			FirstDiscovered,
			LastUpdate,
			LastDataSourceName,
			LastDataSourceType,
			OpenPortsTCP,
			OpenPortsUDP,
			ScannedOperatingSystem,
			ScannedOsType,
			ScannedOsVendor,
			ScannedOsFamily,
			ScannedOsGen,
			ScannedMacAddress,
			ScannedMacVendor,
			SQLDiscoveredBy,
			SQLPorts
		FROM #NetworkDevice
	SET @count = @@ROWCOUNT
	DROP TABLE #NetworkDevice	-- Drop temporary table
	RETURN @count
GO

/*
Add new NetworkDevice bound to
	DeviceRole using Description
	with DuplicateID, ComputerID, DeviceName, DNSFullName, NTDomainName, IPAddress, IPSubnet, IPSubnetMask, PhysicalAddress, OperatingSystem, OperatingSystemID, IsManaged, Description, SystemDescription, SystemLocation, SystemContact, FirstDiscovered, LastUpdate, LastDataSourceName, LastDataSourceType, OpenPortsTCP, OpenPortsUDP, ScannedOperatingSystem, ScannedOsType, ScannedOsVendor, ScannedOsFamily, ScannedOsGen, ScannedMacAddress, ScannedMacVendor, SQLDiscoveredBy, SQLPorts
*/

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[NetworkDeviceUpdateByID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[NetworkDeviceUpdateByID]
GO
CREATE PROCEDURE [dbo].[NetworkDeviceUpdateByID]
	@DeviceID		int,
	@DuplicateID		int = NULL,
	@ComputerID		int = NULL,
	@DeviceName		nvarchar(64) = NULL,
	@DNSFullName		nvarchar(256) = NULL,
	@NTDomainName		nvarchar(256) = NULL,
	@IPAddress		varchar(64) = NULL,
	@IPSubnet		varchar(64) = NULL,
	@IPSubnetMask		varchar(64) = NULL,
	@PhysicalAddress	varchar(64) = NULL,
	@DeviceRole		int = NULL,
	@OperatingSystem	nvarchar(128) = NULL,
	@OperatingSystemID	int = NULL,
	@IsManaged		int = NULL,
	@Description		nvarchar(256) = NULL,
	@SystemDescription	nvarchar(256) = NULL,
	@SystemLocation		nvarchar(256) = NULL,
	@SystemContact		nvarchar(256) = NULL,
	@FirstDiscovered	datetime,
	@LastUpdate		datetime,
	@LastDataSourceName	nvarchar(128) = NULL,
	@LastDataSourceType	nvarchar(32) = NULL,
	@OpenPortsTCP		varchar(512) = NULL,
	@OpenPortsUDP		varchar(512) = NULL,
	@ScannedOperatingSystem	nvarchar(512) = NULL,
	@ScannedOsType		nvarchar(512) = NULL,
	@ScannedOsVendor	nvarchar(512) = NULL,
	@ScannedOsFamily	nvarchar(512) = NULL,
	@ScannedOsGen		nvarchar(512) = NULL,
	@ScannedMacAddress	varchar(64) = NULL,
	@ScannedMacVendor	nvarchar(512) = NULL,
	@SQLDiscoveredBy	nvarchar(128) = NULL,
	@SQLPorts		nvarchar(128) = NULL
AS
	DECLARE	@ID	int
	SET @ID = 0

	UPDATE	[dbo].[NetworkDevice]
	SET	@ID = DeviceID,
		DuplicateID = @DuplicateID,
		ComputerID = @ComputerID,
		DeviceName = @DeviceName,
		DNSFullName = @DNSFullName,
		NTDomainName = @NTDomainName,
		IPAddress = @IPAddress,
		IPSubnet = @IPSubnet,
		IPSubnetMask = @IPSubnetMask,
		PhysicalAddress = @PhysicalAddress,
		DeviceRole = @DeviceRole,
		OperatingSystem = @OperatingSystem,
		OperatingSystemID = @OperatingSystemID,
		IsManaged = @IsManaged,
		Description = @Description,
		SystemDescription = @SystemDescription,
		SystemLocation = @SystemLocation,
		SystemContact = @SystemContact,
		FirstDiscovered = @FirstDiscovered,
		LastUpdate = @LastUpdate,
		LastDataSourceName = @LastDataSourceName,
		LastDataSourceType = @LastDataSourceType,
		OpenPortsTCP = @OpenPortsTCP,
		OpenPortsUDP = @OpenPortsUDP,
		ScannedOperatingSystem = @ScannedOperatingSystem,
		ScannedOsType = @ScannedOsType,
		ScannedOsVendor = @ScannedOsVendor,
		ScannedOsFamily = @ScannedOsFamily,
		ScannedOsGen = @ScannedOsGen,
		ScannedMacAddress = @ScannedMacAddress,
		ScannedMacVendor = @ScannedMacVendor,
		SQLDiscoveredBy = @SQLDiscoveredBy,
		SQLPorts = @SQLPorts
	WHERE	DeviceID = @DeviceID
	RETURN @ID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[NetworkDeviceUpdateBatchByID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[NetworkDeviceUpdateBatchByID]
GO
CREATE PROCEDURE dbo.[NetworkDeviceUpdateBatchByID]
AS
	DECLARE @count int

	CREATE INDEX [TempNetworkDeviceID]
		ON #NetworkDevice (DeviceID)

	UPDATE	[dbo].[NetworkDevice]
	SET	DuplicateID = t.DuplicateID,
		ComputerID = t.ComputerID,
		DeviceName = t.DeviceName,
		DNSFullName = t.DNSFullName,
		NTDomainName = t.NTDomainName,
		IPAddress = t.IPAddress,
		IPSubnet = t.IPSubnet,
		IPSubnetMask = t.IPSubnetMask,
		PhysicalAddress = t.PhysicalAddress,
		DeviceRole = t.DeviceRole,
		OperatingSystem = t.OperatingSystem,
		OperatingSystemID = t.OperatingSystemID,
		IsManaged = t.IsManaged,
		Description = t.Description,
		SystemDescription = t.SystemDescription,
		SystemLocation = t.SystemLocation,
		SystemContact = t.SystemContact,
		FirstDiscovered = t.FirstDiscovered,
		LastUpdate = t.LastUpdate,
		LastDataSourceName = t.LastDataSourceName,
		LastDataSourceType = t.LastDataSourceType,
		OpenPortsTCP = t.OpenPortsTCP,
		OpenPortsUDP = t.OpenPortsUDP,
		ScannedOperatingSystem = t.ScannedOperatingSystem,
		ScannedOsType = t.ScannedOsType,
		ScannedOsVendor = t.ScannedOsVendor,
		ScannedOsFamily = t.ScannedOsFamily,
		ScannedOsGen = t.ScannedOsGen,
		ScannedMacAddress = t.ScannedMacAddress,
		ScannedMacVendor = t.ScannedMacVendor,
		SQLDiscoveredBy = t.SQLDiscoveredBy,
		SQLPorts = t.SQLPorts
	FROM	#NetworkDevice AS t
	WHERE	NetworkDevice.DeviceID = t.DeviceID
	SET @count = @@ROWCOUNT
	DROP TABLE #NetworkDevice	-- Drop the temporary table
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[NetworkDeviceRemoveBatch]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[NetworkDeviceRemoveBatch]
GO

CREATE PROCEDURE [dbo].[NetworkDeviceRemoveBatch]
AS

	CREATE INDEX [TempNetworkDeviceNetworkDeviceRemoveBatch]
		ON #NetworkDevice (DeviceID)	

	-- Delete records from NetworkDevice identified by fields of [TempNetworkDeviceNetworkDeviceRemoveBatch]
	DELETE [dbo].[NetworkDevice]
	WHERE EXISTS(
			SELECT * FROM #NetworkDevice AS t
			WHERE	NetworkDevice.DeviceID = t.DeviceID
		)
	DROP TABLE #NetworkDevice      -- Drop the temporary table
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[NetworkDeviceRemoveByID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[NetworkDeviceRemoveByID]
GO
CREATE PROCEDURE [dbo].[NetworkDeviceRemoveByID]
	@DeviceID		int
AS
	-- NetworkDevice deletes cascade to:
	--	NetworkDeviceCalculatedMember by FK_NetworkDeviceCalculatedMember_NetworkDevice
	--	NetworkDeviceSNMPInfo by FK_NetworkDeviceSNMPInfo_NetworkDevice
	--	NetworkDeviceAMTInfo by FK_NetworkDeviceAMTInfo_NetworkDevice
	--	NetworkDeviceVirtualizationInfo by FK_NetworkDeviceVirtualizationInfo_NetworkDevice
	--	NetworkDeviceDiscoveredBy by FK_NetworkDeviceDiscoveredBy_Device
	--	KnownOracleListener by FK_KnownOracleListener_NetworkDevice
	--		KnownOracleService by FK_KnownOracleService_KnownOracleListener
	--	AgentStatus by FK_AgentStatus_NetworkDevice
	--	AMTEventLog by FK_AMTEventLog_NetworkDevice
	-- NetworkDevice deletes may fail due to non-cascading FKs:
	--	NetworkDevice by FK_NetworkDevice_Duplicate
	--	NetworkDeviceParent by FK_NetworkDeviceChild_NetworkDevice
	--	NetworkDeviceParent by FK_NetworkDeviceParent_NetworkDevice
	--	KnownOracleService by FK_KnownOracleService_NetworkDevice
	--	ActionApplies by FK_ActionApplies_DeviceID
	DELETE	[dbo].[NetworkDevice]
	WHERE	DeviceID = @DeviceID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[NetworkDeviceRemoveAll]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[NetworkDeviceRemoveAll]
GO
CREATE PROCEDURE [dbo].[NetworkDeviceRemoveAll]
	
AS
	DELETE	[dbo].[NetworkDevice]
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[NetworkDeviceCalculatedMemberGetByDeviceID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[NetworkDeviceCalculatedMemberGetByDeviceID]
GO
CREATE PROCEDURE [dbo].[NetworkDeviceCalculatedMemberGetByDeviceID]
	@DeviceID		int
AS
	SELECT	DeviceID,
		IsOracle,
		OracleListeners,
		OracleServices,
		IsSQL
	FROM	[dbo].[NetworkDeviceCalculatedMember]
	WHERE	DeviceID = @DeviceID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[NetworkDeviceCalculatedMemberGetAll]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[NetworkDeviceCalculatedMemberGetAll]
GO
CREATE PROCEDURE [dbo].[NetworkDeviceCalculatedMemberGetAll]
AS
	SELECT	DeviceID,
		IsOracle,
		OracleListeners,
		OracleServices,
		IsSQL
	FROM	[dbo].[NetworkDeviceCalculatedMember]
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[NetworkDeviceCalculatedMemberAdd]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[NetworkDeviceCalculatedMemberAdd]
GO
CREATE PROCEDURE [dbo].[NetworkDeviceCalculatedMemberAdd]
	@DeviceID		int,
	@IsOracle		bit = 0,
	@OracleListeners	nvarchar(512) = NULL,
	@OracleServices		nvarchar(512) = NULL,
	@IsSQL			bit = 0
AS
	INSERT INTO  dbo.NetworkDeviceCalculatedMember (
		DeviceID,
		IsOracle,
		OracleListeners,
		OracleServices,
		IsSQL
	)
	VALUES (
		@DeviceID,
		@IsOracle,
		@OracleListeners,
		@OracleServices,
		@IsSQL
	)
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[NetworkDeviceCalculatedMemberSchema]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[NetworkDeviceCalculatedMemberSchema]
GO
CREATE PROCEDURE [dbo].[NetworkDeviceCalculatedMemberSchema]
AS
	SELECT
	'IF OBJECT_ID(''tempdb..#NetworkDeviceCalculatedMember'') IS NULL' + CAST(0x0A AS CHAR(1)) +
	'	CREATE TABLE #NetworkDeviceCalculatedMember (' + CAST(0x0A AS CHAR(1)) +
	'		DeviceID		int NOT NULL,' + CAST(0x0A AS CHAR(1)) +
	'		IsOracle		bit NULL DEFAULT 0,' + CAST(0x0A AS CHAR(1)) +
	'		OracleListeners		nvarchar(512) COLLATE database_default NULL,' + CAST(0x0A AS CHAR(1)) +
	'		OracleServices		nvarchar(512) COLLATE database_default NULL,' + CAST(0x0A AS CHAR(1)) +
	'		IsSQL			bit NULL DEFAULT 0' + CAST(0x0A AS CHAR(1)) +
	'	)' + CAST(0x0A AS CHAR(1)) +
	'ELSE' + CAST(0x0A AS CHAR(1)) +
	'	DELETE FROM #NetworkDeviceCalculatedMember' + CAST(0x0A AS CHAR(1)) +
	'' AS SQL
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[NetworkDeviceCalculatedMemberTempAdd]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[NetworkDeviceCalculatedMemberTempAdd]
GO
CREATE PROCEDURE dbo.[NetworkDeviceCalculatedMemberTempAdd]
	@DeviceID		int,
	@IsOracle		bit = 0,
	@OracleListeners	nvarchar(512) = NULL,
	@OracleServices		nvarchar(512) = NULL,
	@IsSQL			bit = 0
AS
	INSERT INTO #NetworkDeviceCalculatedMember (
		DeviceID,
		IsOracle,
		OracleListeners,
		OracleServices,
		IsSQL
	)
	VALUES (
		@DeviceID,
		@IsOracle,
		@OracleListeners,
		@OracleServices,
		@IsSQL
	)
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[NetworkDeviceCalculatedMemberAddBatch]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[NetworkDeviceCalculatedMemberAddBatch]
GO
CREATE PROCEDURE dbo.[NetworkDeviceCalculatedMemberAddBatch]
AS
	DECLARE @count int
	INSERT dbo.NetworkDeviceCalculatedMember (
		DeviceID,
		IsOracle,
		OracleListeners,
		OracleServices,
		IsSQL
	)
		SELECT	DeviceID,
			IsOracle,
			OracleListeners,
			OracleServices,
			IsSQL
		FROM #NetworkDeviceCalculatedMember
	SET @count = @@ROWCOUNT
	DROP TABLE #NetworkDeviceCalculatedMember	-- Drop temporary table
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[NetworkDeviceCalculatedMemberUpdateByDeviceID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[NetworkDeviceCalculatedMemberUpdateByDeviceID]
GO
CREATE PROCEDURE [dbo].[NetworkDeviceCalculatedMemberUpdateByDeviceID]
	@DeviceID		int,
	@IsOracle		bit = 0,
	@OracleListeners	nvarchar(512) = NULL,
	@OracleServices		nvarchar(512) = NULL,
	@IsSQL			bit = 0
AS
	UPDATE	[dbo].[NetworkDeviceCalculatedMember]
	SET	IsOracle = @IsOracle,
		OracleListeners = @OracleListeners,
		OracleServices = @OracleServices,
		IsSQL = @IsSQL
	WHERE	DeviceID = @DeviceID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[NetworkDeviceCalculatedMemberUpdateBatchByDeviceID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[NetworkDeviceCalculatedMemberUpdateBatchByDeviceID]
GO
CREATE PROCEDURE dbo.[NetworkDeviceCalculatedMemberUpdateBatchByDeviceID]
AS
	DECLARE @count int

	CREATE INDEX [TempNetworkDeviceCalculatedMemberDeviceID]
		ON #NetworkDeviceCalculatedMember (DeviceID)

	UPDATE	[dbo].[NetworkDeviceCalculatedMember]
	SET	IsOracle = t.IsOracle,
		OracleListeners = t.OracleListeners,
		OracleServices = t.OracleServices,
		IsSQL = t.IsSQL
	FROM	#NetworkDeviceCalculatedMember AS t
	WHERE	NetworkDeviceCalculatedMember.DeviceID = t.DeviceID
	SET @count = @@ROWCOUNT
	DROP TABLE #NetworkDeviceCalculatedMember	-- Drop the temporary table
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[NetworkDeviceCalculatedMemberPutByDeviceID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[NetworkDeviceCalculatedMemberPutByDeviceID]
GO
CREATE PROCEDURE [dbo].[NetworkDeviceCalculatedMemberPutByDeviceID]
	@DeviceID		int,
	@IsOracle		bit = 0,
	@OracleListeners	nvarchar(512) = NULL,
	@OracleServices		nvarchar(512) = NULL,
	@IsSQL			bit = 0
AS
	IF NOT EXISTS(
		SELECT	1
		FROM	dbo.NetworkDeviceCalculatedMember
		WHERE	DeviceID = @DeviceID
	)
		EXEC NetworkDeviceCalculatedMemberAdd @DeviceID,
			@IsOracle,
			@OracleListeners,
			@OracleServices,
			@IsSQL
	ELSE
		EXEC NetworkDeviceCalculatedMemberUpdateByDeviceID @DeviceID,
			@IsOracle,
			@OracleListeners,
			@OracleServices,
			@IsSQL
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[NetworkDeviceCalculatedMemberPutBatchByDeviceID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[NetworkDeviceCalculatedMemberPutBatchByDeviceID]
GO
CREATE PROCEDURE [dbo].[NetworkDeviceCalculatedMemberPutBatchByDeviceID]
AS
	DECLARE @count AS int
	SET @count = 0

	CREATE INDEX [TempNetworkDeviceCalculatedMemberDeviceID]
		ON #NetworkDeviceCalculatedMember (DeviceID)

	BEGIN TRANSACTION
	UPDATE [dbo].[NetworkDeviceCalculatedMember]
		SET	IsOracle = t.IsOracle,
			OracleListeners = t.OracleListeners,
			OracleServices = t.OracleServices,
			IsSQL = t.IsSQL
		FROM	#NetworkDeviceCalculatedMember AS t
		WHERE	NetworkDeviceCalculatedMember.DeviceID = t.DeviceID
	SET @count = @@ROWCOUNT

	INSERT [dbo].[NetworkDeviceCalculatedMember] (
		DeviceID,
		IsOracle,
		OracleListeners,
		OracleServices,
		IsSQL
	)
		SELECT	DeviceID,
			IsOracle,
			OracleListeners,
			OracleServices,
			IsSQL
		FROM	#NetworkDeviceCalculatedMember AS t
		WHERE NOT EXISTS(	-- Current record doesn't exist
			SELECT * FROM [dbo].[NetworkDeviceCalculatedMember]
			WHERE	NetworkDeviceCalculatedMember.DeviceID = t.DeviceID
		)
	SET @count = @count + @@ROWCOUNT
	DROP TABLE #NetworkDeviceCalculatedMember	-- Drop the temporary table
	COMMIT WORK
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[NetworkDeviceCalculatedMemberRemoveBatch]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[NetworkDeviceCalculatedMemberRemoveBatch]
GO

CREATE PROCEDURE [dbo].[NetworkDeviceCalculatedMemberRemoveBatch]
AS

	CREATE INDEX [TempNetworkDeviceCalculatedMemberNetworkDeviceCalculatedMemberRemoveBatch]
		ON #NetworkDeviceCalculatedMember (DeviceID)	

	-- Delete records from NetworkDeviceCalculatedMember identified by fields of [TempNetworkDeviceCalculatedMemberNetworkDeviceCalculatedMemberRemoveBatch]
	DELETE [dbo].[NetworkDeviceCalculatedMember]
	WHERE EXISTS(
			SELECT * FROM #NetworkDeviceCalculatedMember AS t
			WHERE	NetworkDeviceCalculatedMember.DeviceID = t.DeviceID
		)
	DROP TABLE #NetworkDeviceCalculatedMember      -- Drop the temporary table
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[NetworkDeviceCalculatedMemberRemoveByDeviceID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[NetworkDeviceCalculatedMemberRemoveByDeviceID]
GO
CREATE PROCEDURE [dbo].[NetworkDeviceCalculatedMemberRemoveByDeviceID]
	@DeviceID		int
AS
	DELETE	[dbo].[NetworkDeviceCalculatedMember]
	WHERE	DeviceID = @DeviceID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[NetworkDeviceCalculatedMemberRemoveAll]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[NetworkDeviceCalculatedMemberRemoveAll]
GO
CREATE PROCEDURE [dbo].[NetworkDeviceCalculatedMemberRemoveAll]
	
AS
	DELETE	[dbo].[NetworkDeviceCalculatedMember]
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[NetworkDeviceSNMPInfoGetByDeviceID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[NetworkDeviceSNMPInfoGetByDeviceID]
GO
CREATE PROCEDURE [dbo].[NetworkDeviceSNMPInfoGetByDeviceID]
	@DeviceID		int
AS
	SELECT	DeviceID,
		SNMP_snmpCommunityString,
		SNMP_sysDescr,
		SNMP_sysObjectID,
		SNMP_sysObjectIDSymbolic,
		SNMP_sysUpTime,
		SNMP_sysContact,
		SNMP_sysName,
		SNMP_sysLocation,
		SNMP_sysServices,
		SNMP_ipForwarding
	FROM	[dbo].[NetworkDeviceSNMPInfo]
	WHERE	DeviceID = @DeviceID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[NetworkDeviceSNMPInfoGetAll]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[NetworkDeviceSNMPInfoGetAll]
GO
CREATE PROCEDURE [dbo].[NetworkDeviceSNMPInfoGetAll]
AS
	SELECT	DeviceID,
		SNMP_snmpCommunityString,
		SNMP_sysDescr,
		SNMP_sysObjectID,
		SNMP_sysObjectIDSymbolic,
		SNMP_sysUpTime,
		SNMP_sysContact,
		SNMP_sysName,
		SNMP_sysLocation,
		SNMP_sysServices,
		SNMP_ipForwarding
	FROM	[dbo].[NetworkDeviceSNMPInfo]
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[NetworkDeviceSNMPInfoAdd]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[NetworkDeviceSNMPInfoAdd]
GO
CREATE PROCEDURE [dbo].[NetworkDeviceSNMPInfoAdd]
	@DeviceID		int,
	@SNMP_snmpCommunityString nvarchar(256) = NULL,
	@SNMP_sysDescr		nvarchar(256) = NULL,
	@SNMP_sysObjectID	nvarchar(256) = NULL,
	@SNMP_sysObjectIDSymbolic nvarchar(256) = NULL,
	@SNMP_sysUpTime		bigint = NULL,
	@SNMP_sysContact	nvarchar(256) = NULL,
	@SNMP_sysName		nvarchar(256) = NULL,
	@SNMP_sysLocation	nvarchar(256) = NULL,
	@SNMP_sysServices	int = NULL,
	@SNMP_ipForwarding	int = NULL
AS
	INSERT INTO  dbo.NetworkDeviceSNMPInfo (
		DeviceID,
		SNMP_snmpCommunityString,
		SNMP_sysDescr,
		SNMP_sysObjectID,
		SNMP_sysObjectIDSymbolic,
		SNMP_sysUpTime,
		SNMP_sysContact,
		SNMP_sysName,
		SNMP_sysLocation,
		SNMP_sysServices,
		SNMP_ipForwarding
	)
	VALUES (
		@DeviceID,
		@SNMP_snmpCommunityString,
		@SNMP_sysDescr,
		@SNMP_sysObjectID,
		@SNMP_sysObjectIDSymbolic,
		@SNMP_sysUpTime,
		@SNMP_sysContact,
		@SNMP_sysName,
		@SNMP_sysLocation,
		@SNMP_sysServices,
		@SNMP_ipForwarding
	)
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[NetworkDeviceSNMPInfoSchema]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[NetworkDeviceSNMPInfoSchema]
GO
CREATE PROCEDURE [dbo].[NetworkDeviceSNMPInfoSchema]
AS
	SELECT
	'IF OBJECT_ID(''tempdb..#NetworkDeviceSNMPInfo'') IS NULL' + CAST(0x0A AS CHAR(1)) +
	'	CREATE TABLE #NetworkDeviceSNMPInfo (' + CAST(0x0A AS CHAR(1)) +
	'		DeviceID		int NOT NULL,' + CAST(0x0A AS CHAR(1)) +
	'		SNMP_snmpCommunityString nvarchar(256) COLLATE database_default NULL,' + CAST(0x0A AS CHAR(1)) +
	'		SNMP_sysDescr		nvarchar(256) COLLATE database_default NULL,' + CAST(0x0A AS CHAR(1)) +
	'		SNMP_sysObjectID	nvarchar(256) COLLATE database_default NULL,' + CAST(0x0A AS CHAR(1)) +
	'		SNMP_sysObjectIDSymbolic nvarchar(256) COLLATE database_default NULL,' + CAST(0x0A AS CHAR(1)) +
	'		SNMP_sysUpTime		bigint NULL,' + CAST(0x0A AS CHAR(1)) +
	'		SNMP_sysContact		nvarchar(256) COLLATE database_default NULL,' + CAST(0x0A AS CHAR(1)) +
	'		SNMP_sysName		nvarchar(256) COLLATE database_default NULL,' + CAST(0x0A AS CHAR(1)) +
	'		SNMP_sysLocation	nvarchar(256) COLLATE database_default NULL,' + CAST(0x0A AS CHAR(1)) +
	'		SNMP_sysServices	int NULL,' + CAST(0x0A AS CHAR(1)) +
	'		SNMP_ipForwarding	int NULL' + CAST(0x0A AS CHAR(1)) +
	'	)' + CAST(0x0A AS CHAR(1)) +
	'ELSE' + CAST(0x0A AS CHAR(1)) +
	'	DELETE FROM #NetworkDeviceSNMPInfo' + CAST(0x0A AS CHAR(1)) +
	'' AS SQL
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[NetworkDeviceSNMPInfoTempAdd]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[NetworkDeviceSNMPInfoTempAdd]
GO
CREATE PROCEDURE dbo.[NetworkDeviceSNMPInfoTempAdd]
	@DeviceID		int,
	@SNMP_snmpCommunityString nvarchar(256) = NULL,
	@SNMP_sysDescr		nvarchar(256) = NULL,
	@SNMP_sysObjectID	nvarchar(256) = NULL,
	@SNMP_sysObjectIDSymbolic nvarchar(256) = NULL,
	@SNMP_sysUpTime		bigint = NULL,
	@SNMP_sysContact	nvarchar(256) = NULL,
	@SNMP_sysName		nvarchar(256) = NULL,
	@SNMP_sysLocation	nvarchar(256) = NULL,
	@SNMP_sysServices	int = NULL,
	@SNMP_ipForwarding	int = NULL
AS
	INSERT INTO #NetworkDeviceSNMPInfo (
		DeviceID,
		SNMP_snmpCommunityString,
		SNMP_sysDescr,
		SNMP_sysObjectID,
		SNMP_sysObjectIDSymbolic,
		SNMP_sysUpTime,
		SNMP_sysContact,
		SNMP_sysName,
		SNMP_sysLocation,
		SNMP_sysServices,
		SNMP_ipForwarding
	)
	VALUES (
		@DeviceID,
		@SNMP_snmpCommunityString,
		@SNMP_sysDescr,
		@SNMP_sysObjectID,
		@SNMP_sysObjectIDSymbolic,
		@SNMP_sysUpTime,
		@SNMP_sysContact,
		@SNMP_sysName,
		@SNMP_sysLocation,
		@SNMP_sysServices,
		@SNMP_ipForwarding
	)
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[NetworkDeviceSNMPInfoAddBatch]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[NetworkDeviceSNMPInfoAddBatch]
GO
CREATE PROCEDURE dbo.[NetworkDeviceSNMPInfoAddBatch]
AS
	DECLARE @count int
	INSERT dbo.NetworkDeviceSNMPInfo (
		DeviceID,
		SNMP_snmpCommunityString,
		SNMP_sysDescr,
		SNMP_sysObjectID,
		SNMP_sysObjectIDSymbolic,
		SNMP_sysUpTime,
		SNMP_sysContact,
		SNMP_sysName,
		SNMP_sysLocation,
		SNMP_sysServices,
		SNMP_ipForwarding
	)
		SELECT	DeviceID,
			SNMP_snmpCommunityString,
			SNMP_sysDescr,
			SNMP_sysObjectID,
			SNMP_sysObjectIDSymbolic,
			SNMP_sysUpTime,
			SNMP_sysContact,
			SNMP_sysName,
			SNMP_sysLocation,
			SNMP_sysServices,
			SNMP_ipForwarding
		FROM #NetworkDeviceSNMPInfo
	SET @count = @@ROWCOUNT
	DROP TABLE #NetworkDeviceSNMPInfo	-- Drop temporary table
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[NetworkDeviceSNMPInfoUpdateByDeviceID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[NetworkDeviceSNMPInfoUpdateByDeviceID]
GO
CREATE PROCEDURE [dbo].[NetworkDeviceSNMPInfoUpdateByDeviceID]
	@DeviceID		int,
	@SNMP_snmpCommunityString nvarchar(256) = NULL,
	@SNMP_sysDescr		nvarchar(256) = NULL,
	@SNMP_sysObjectID	nvarchar(256) = NULL,
	@SNMP_sysObjectIDSymbolic nvarchar(256) = NULL,
	@SNMP_sysUpTime		bigint = NULL,
	@SNMP_sysContact	nvarchar(256) = NULL,
	@SNMP_sysName		nvarchar(256) = NULL,
	@SNMP_sysLocation	nvarchar(256) = NULL,
	@SNMP_sysServices	int = NULL,
	@SNMP_ipForwarding	int = NULL
AS
	UPDATE	[dbo].[NetworkDeviceSNMPInfo]
	SET	SNMP_snmpCommunityString = @SNMP_snmpCommunityString,
		SNMP_sysDescr = @SNMP_sysDescr,
		SNMP_sysObjectID = @SNMP_sysObjectID,
		SNMP_sysObjectIDSymbolic = @SNMP_sysObjectIDSymbolic,
		SNMP_sysUpTime = @SNMP_sysUpTime,
		SNMP_sysContact = @SNMP_sysContact,
		SNMP_sysName = @SNMP_sysName,
		SNMP_sysLocation = @SNMP_sysLocation,
		SNMP_sysServices = @SNMP_sysServices,
		SNMP_ipForwarding = @SNMP_ipForwarding
	WHERE	DeviceID = @DeviceID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[NetworkDeviceSNMPInfoUpdateBatchByDeviceID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[NetworkDeviceSNMPInfoUpdateBatchByDeviceID]
GO
CREATE PROCEDURE dbo.[NetworkDeviceSNMPInfoUpdateBatchByDeviceID]
AS
	DECLARE @count int

	CREATE INDEX [TempNetworkDeviceSNMPInfoDeviceID]
		ON #NetworkDeviceSNMPInfo (DeviceID)

	UPDATE	[dbo].[NetworkDeviceSNMPInfo]
	SET	SNMP_snmpCommunityString = t.SNMP_snmpCommunityString,
		SNMP_sysDescr = t.SNMP_sysDescr,
		SNMP_sysObjectID = t.SNMP_sysObjectID,
		SNMP_sysObjectIDSymbolic = t.SNMP_sysObjectIDSymbolic,
		SNMP_sysUpTime = t.SNMP_sysUpTime,
		SNMP_sysContact = t.SNMP_sysContact,
		SNMP_sysName = t.SNMP_sysName,
		SNMP_sysLocation = t.SNMP_sysLocation,
		SNMP_sysServices = t.SNMP_sysServices,
		SNMP_ipForwarding = t.SNMP_ipForwarding
	FROM	#NetworkDeviceSNMPInfo AS t
	WHERE	NetworkDeviceSNMPInfo.DeviceID = t.DeviceID
	SET @count = @@ROWCOUNT
	DROP TABLE #NetworkDeviceSNMPInfo	-- Drop the temporary table
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[NetworkDeviceSNMPInfoPutByDeviceID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[NetworkDeviceSNMPInfoPutByDeviceID]
GO
CREATE PROCEDURE [dbo].[NetworkDeviceSNMPInfoPutByDeviceID]
	@DeviceID		int,
	@SNMP_snmpCommunityString nvarchar(256) = NULL,
	@SNMP_sysDescr		nvarchar(256) = NULL,
	@SNMP_sysObjectID	nvarchar(256) = NULL,
	@SNMP_sysObjectIDSymbolic nvarchar(256) = NULL,
	@SNMP_sysUpTime		bigint = NULL,
	@SNMP_sysContact	nvarchar(256) = NULL,
	@SNMP_sysName		nvarchar(256) = NULL,
	@SNMP_sysLocation	nvarchar(256) = NULL,
	@SNMP_sysServices	int = NULL,
	@SNMP_ipForwarding	int = NULL
AS
	IF NOT EXISTS(
		SELECT	1
		FROM	dbo.NetworkDeviceSNMPInfo
		WHERE	DeviceID = @DeviceID
	)
		EXEC NetworkDeviceSNMPInfoAdd @DeviceID,
			@SNMP_snmpCommunityString,
			@SNMP_sysDescr,
			@SNMP_sysObjectID,
			@SNMP_sysObjectIDSymbolic,
			@SNMP_sysUpTime,
			@SNMP_sysContact,
			@SNMP_sysName,
			@SNMP_sysLocation,
			@SNMP_sysServices,
			@SNMP_ipForwarding
	ELSE
		EXEC NetworkDeviceSNMPInfoUpdateByDeviceID @DeviceID,
			@SNMP_snmpCommunityString,
			@SNMP_sysDescr,
			@SNMP_sysObjectID,
			@SNMP_sysObjectIDSymbolic,
			@SNMP_sysUpTime,
			@SNMP_sysContact,
			@SNMP_sysName,
			@SNMP_sysLocation,
			@SNMP_sysServices,
			@SNMP_ipForwarding
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[NetworkDeviceSNMPInfoPutBatchByDeviceID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[NetworkDeviceSNMPInfoPutBatchByDeviceID]
GO
CREATE PROCEDURE [dbo].[NetworkDeviceSNMPInfoPutBatchByDeviceID]
AS
	DECLARE @count AS int
	SET @count = 0

	CREATE INDEX [TempNetworkDeviceSNMPInfoDeviceID]
		ON #NetworkDeviceSNMPInfo (DeviceID)

	BEGIN TRANSACTION
	UPDATE [dbo].[NetworkDeviceSNMPInfo]
		SET	SNMP_snmpCommunityString = t.SNMP_snmpCommunityString,
			SNMP_sysDescr = t.SNMP_sysDescr,
			SNMP_sysObjectID = t.SNMP_sysObjectID,
			SNMP_sysObjectIDSymbolic = t.SNMP_sysObjectIDSymbolic,
			SNMP_sysUpTime = t.SNMP_sysUpTime,
			SNMP_sysContact = t.SNMP_sysContact,
			SNMP_sysName = t.SNMP_sysName,
			SNMP_sysLocation = t.SNMP_sysLocation,
			SNMP_sysServices = t.SNMP_sysServices,
			SNMP_ipForwarding = t.SNMP_ipForwarding
		FROM	#NetworkDeviceSNMPInfo AS t
		WHERE	NetworkDeviceSNMPInfo.DeviceID = t.DeviceID
	SET @count = @@ROWCOUNT

	INSERT [dbo].[NetworkDeviceSNMPInfo] (
		DeviceID,
		SNMP_snmpCommunityString,
		SNMP_sysDescr,
		SNMP_sysObjectID,
		SNMP_sysObjectIDSymbolic,
		SNMP_sysUpTime,
		SNMP_sysContact,
		SNMP_sysName,
		SNMP_sysLocation,
		SNMP_sysServices,
		SNMP_ipForwarding
	)
		SELECT	DeviceID,
			SNMP_snmpCommunityString,
			SNMP_sysDescr,
			SNMP_sysObjectID,
			SNMP_sysObjectIDSymbolic,
			SNMP_sysUpTime,
			SNMP_sysContact,
			SNMP_sysName,
			SNMP_sysLocation,
			SNMP_sysServices,
			SNMP_ipForwarding
		FROM	#NetworkDeviceSNMPInfo AS t
		WHERE NOT EXISTS(	-- Current record doesn't exist
			SELECT * FROM [dbo].[NetworkDeviceSNMPInfo]
			WHERE	NetworkDeviceSNMPInfo.DeviceID = t.DeviceID
		)
	SET @count = @count + @@ROWCOUNT
	DROP TABLE #NetworkDeviceSNMPInfo	-- Drop the temporary table
	COMMIT WORK
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[NetworkDeviceSNMPInfoRemoveBatch]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[NetworkDeviceSNMPInfoRemoveBatch]
GO

CREATE PROCEDURE [dbo].[NetworkDeviceSNMPInfoRemoveBatch]
AS

	CREATE INDEX [TempNetworkDeviceSNMPInfoNetworkDeviceSNMPInfoRemoveBatch]
		ON #NetworkDeviceSNMPInfo (DeviceID)	

	-- Delete records from NetworkDeviceSNMPInfo identified by fields of [TempNetworkDeviceSNMPInfoNetworkDeviceSNMPInfoRemoveBatch]
	DELETE [dbo].[NetworkDeviceSNMPInfo]
	WHERE EXISTS(
			SELECT * FROM #NetworkDeviceSNMPInfo AS t
			WHERE	NetworkDeviceSNMPInfo.DeviceID = t.DeviceID
		)
	DROP TABLE #NetworkDeviceSNMPInfo      -- Drop the temporary table
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[NetworkDeviceSNMPInfoRemoveByDeviceID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[NetworkDeviceSNMPInfoRemoveByDeviceID]
GO
CREATE PROCEDURE [dbo].[NetworkDeviceSNMPInfoRemoveByDeviceID]
	@DeviceID		int
AS
	DELETE	[dbo].[NetworkDeviceSNMPInfo]
	WHERE	DeviceID = @DeviceID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[NetworkDeviceSNMPInfoRemoveAll]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[NetworkDeviceSNMPInfoRemoveAll]
GO
CREATE PROCEDURE [dbo].[NetworkDeviceSNMPInfoRemoveAll]
	
AS
	DELETE	[dbo].[NetworkDeviceSNMPInfo]
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[NetworkDeviceAMTInfoGetByDeviceID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[NetworkDeviceAMTInfoGetByDeviceID]
GO
CREATE PROCEDURE [dbo].[NetworkDeviceAMTInfoGetByDeviceID]
	@DeviceID		int
AS
	SELECT	DeviceID,
		Secure,
		Description
	FROM	[dbo].[NetworkDeviceAMTInfo]
	WHERE	DeviceID = @DeviceID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[NetworkDeviceAMTInfoGetAll]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[NetworkDeviceAMTInfoGetAll]
GO
CREATE PROCEDURE [dbo].[NetworkDeviceAMTInfoGetAll]
AS
	SELECT	DeviceID,
		Secure,
		Description
	FROM	[dbo].[NetworkDeviceAMTInfo]
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[NetworkDeviceAMTInfoAdd]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[NetworkDeviceAMTInfoAdd]
GO
CREATE PROCEDURE [dbo].[NetworkDeviceAMTInfoAdd]
	@DeviceID		int,
	@Secure			int = NULL,
	@Description		nvarchar(256) = NULL
AS
	INSERT INTO  dbo.NetworkDeviceAMTInfo (
		DeviceID,
		Secure,
		Description
	)
	VALUES (
		@DeviceID,
		@Secure,
		@Description
	)
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[NetworkDeviceAMTInfoSchema]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[NetworkDeviceAMTInfoSchema]
GO
CREATE PROCEDURE [dbo].[NetworkDeviceAMTInfoSchema]
AS
	SELECT
	'IF OBJECT_ID(''tempdb..#NetworkDeviceAMTInfo'') IS NULL' + CAST(0x0A AS CHAR(1)) +
	'	CREATE TABLE #NetworkDeviceAMTInfo (' + CAST(0x0A AS CHAR(1)) +
	'		DeviceID		int NOT NULL,' + CAST(0x0A AS CHAR(1)) +
	'		Secure			int NULL,' + CAST(0x0A AS CHAR(1)) +
	'		Description		nvarchar(256) COLLATE database_default NULL' + CAST(0x0A AS CHAR(1)) +
	'	)' + CAST(0x0A AS CHAR(1)) +
	'ELSE' + CAST(0x0A AS CHAR(1)) +
	'	DELETE FROM #NetworkDeviceAMTInfo' + CAST(0x0A AS CHAR(1)) +
	'' AS SQL
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[NetworkDeviceAMTInfoTempAdd]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[NetworkDeviceAMTInfoTempAdd]
GO
CREATE PROCEDURE dbo.[NetworkDeviceAMTInfoTempAdd]
	@DeviceID		int,
	@Secure			int = NULL,
	@Description		nvarchar(256) = NULL
AS
	INSERT INTO #NetworkDeviceAMTInfo (
		DeviceID,
		Secure,
		Description
	)
	VALUES (
		@DeviceID,
		@Secure,
		@Description
	)
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[NetworkDeviceAMTInfoAddBatch]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[NetworkDeviceAMTInfoAddBatch]
GO
CREATE PROCEDURE dbo.[NetworkDeviceAMTInfoAddBatch]
AS
	DECLARE @count int
	INSERT dbo.NetworkDeviceAMTInfo (
		DeviceID,
		Secure,
		Description
	)
		SELECT	DeviceID,
			Secure,
			Description
		FROM #NetworkDeviceAMTInfo
	SET @count = @@ROWCOUNT
	DROP TABLE #NetworkDeviceAMTInfo	-- Drop temporary table
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[NetworkDeviceAMTInfoUpdateByDeviceID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[NetworkDeviceAMTInfoUpdateByDeviceID]
GO
CREATE PROCEDURE [dbo].[NetworkDeviceAMTInfoUpdateByDeviceID]
	@DeviceID		int,
	@Secure			int = NULL,
	@Description		nvarchar(256) = NULL
AS
	UPDATE	[dbo].[NetworkDeviceAMTInfo]
	SET	Secure = @Secure,
		Description = @Description
	WHERE	DeviceID = @DeviceID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[NetworkDeviceAMTInfoUpdateBatchByDeviceID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[NetworkDeviceAMTInfoUpdateBatchByDeviceID]
GO
CREATE PROCEDURE dbo.[NetworkDeviceAMTInfoUpdateBatchByDeviceID]
AS
	DECLARE @count int

	CREATE INDEX [TempNetworkDeviceAMTInfoDeviceID]
		ON #NetworkDeviceAMTInfo (DeviceID)

	UPDATE	[dbo].[NetworkDeviceAMTInfo]
	SET	Secure = t.Secure,
		Description = t.Description
	FROM	#NetworkDeviceAMTInfo AS t
	WHERE	NetworkDeviceAMTInfo.DeviceID = t.DeviceID
	SET @count = @@ROWCOUNT
	DROP TABLE #NetworkDeviceAMTInfo	-- Drop the temporary table
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[NetworkDeviceAMTInfoPutByDeviceID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[NetworkDeviceAMTInfoPutByDeviceID]
GO
CREATE PROCEDURE [dbo].[NetworkDeviceAMTInfoPutByDeviceID]
	@DeviceID		int,
	@Secure			int = NULL,
	@Description		nvarchar(256) = NULL
AS
	IF NOT EXISTS(
		SELECT	1
		FROM	dbo.NetworkDeviceAMTInfo
		WHERE	DeviceID = @DeviceID
	)
		EXEC NetworkDeviceAMTInfoAdd @DeviceID,
			@Secure,
			@Description
	ELSE
		EXEC NetworkDeviceAMTInfoUpdateByDeviceID @DeviceID,
			@Secure,
			@Description
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[NetworkDeviceAMTInfoPutBatchByDeviceID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[NetworkDeviceAMTInfoPutBatchByDeviceID]
GO
CREATE PROCEDURE [dbo].[NetworkDeviceAMTInfoPutBatchByDeviceID]
AS
	DECLARE @count AS int
	SET @count = 0

	CREATE INDEX [TempNetworkDeviceAMTInfoDeviceID]
		ON #NetworkDeviceAMTInfo (DeviceID)

	BEGIN TRANSACTION
	UPDATE [dbo].[NetworkDeviceAMTInfo]
		SET	Secure = t.Secure,
			Description = t.Description
		FROM	#NetworkDeviceAMTInfo AS t
		WHERE	NetworkDeviceAMTInfo.DeviceID = t.DeviceID
	SET @count = @@ROWCOUNT

	INSERT [dbo].[NetworkDeviceAMTInfo] (
		DeviceID,
		Secure,
		Description
	)
		SELECT	DeviceID,
			Secure,
			Description
		FROM	#NetworkDeviceAMTInfo AS t
		WHERE NOT EXISTS(	-- Current record doesn't exist
			SELECT * FROM [dbo].[NetworkDeviceAMTInfo]
			WHERE	NetworkDeviceAMTInfo.DeviceID = t.DeviceID
		)
	SET @count = @count + @@ROWCOUNT
	DROP TABLE #NetworkDeviceAMTInfo	-- Drop the temporary table
	COMMIT WORK
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[NetworkDeviceAMTInfoRemoveBatch]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[NetworkDeviceAMTInfoRemoveBatch]
GO

CREATE PROCEDURE [dbo].[NetworkDeviceAMTInfoRemoveBatch]
AS

	CREATE INDEX [TempNetworkDeviceAMTInfoNetworkDeviceAMTInfoRemoveBatch]
		ON #NetworkDeviceAMTInfo (DeviceID)	

	-- Delete records from NetworkDeviceAMTInfo identified by fields of [TempNetworkDeviceAMTInfoNetworkDeviceAMTInfoRemoveBatch]
	DELETE [dbo].[NetworkDeviceAMTInfo]
	WHERE EXISTS(
			SELECT * FROM #NetworkDeviceAMTInfo AS t
			WHERE	NetworkDeviceAMTInfo.DeviceID = t.DeviceID
		)
	DROP TABLE #NetworkDeviceAMTInfo      -- Drop the temporary table
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[NetworkDeviceAMTInfoRemoveByDeviceID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[NetworkDeviceAMTInfoRemoveByDeviceID]
GO
CREATE PROCEDURE [dbo].[NetworkDeviceAMTInfoRemoveByDeviceID]
	@DeviceID		int
AS
	DELETE	[dbo].[NetworkDeviceAMTInfo]
	WHERE	DeviceID = @DeviceID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[NetworkDeviceAMTInfoRemoveAll]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[NetworkDeviceAMTInfoRemoveAll]
GO
CREATE PROCEDURE [dbo].[NetworkDeviceAMTInfoRemoveAll]
	
AS
	DELETE	[dbo].[NetworkDeviceAMTInfo]
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[VirtualizationProductNameGetByID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[VirtualizationProductNameGetByID]
GO
CREATE PROCEDURE [dbo].[VirtualizationProductNameGetByID]
	@VirtualizationProductNameID int
AS
	SELECT	VirtualizationProductNameID,
		ProductName
	FROM	[dbo].[VirtualizationProductName]
	WHERE	VirtualizationProductNameID = @VirtualizationProductNameID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[VirtualizationProductNameGetByProductName]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[VirtualizationProductNameGetByProductName]
GO
CREATE PROCEDURE [dbo].[VirtualizationProductNameGetByProductName]
	@ProductName		nvarchar(256)
AS
	SELECT	VirtualizationProductNameID,
		ProductName
	FROM	[dbo].[VirtualizationProductName]
	WHERE	ProductName = @ProductName
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[VirtualizationProductNameGetAll]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[VirtualizationProductNameGetAll]
GO
CREATE PROCEDURE [dbo].[VirtualizationProductNameGetAll]
AS
	SELECT	VirtualizationProductNameID,
		ProductName
	FROM	[dbo].[VirtualizationProductName]
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[VirtualizationProductNameAdd]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[VirtualizationProductNameAdd]
GO
CREATE PROCEDURE [dbo].[VirtualizationProductNameAdd]
	@ProductName		nvarchar(256)
AS
	INSERT INTO  dbo.VirtualizationProductName (
		ProductName
	)
	VALUES (
		@ProductName
	)
	RETURN SCOPE_IDENTITY()
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[VirtualizationProductNameBind]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[VirtualizationProductNameBind]
GO
CREATE PROCEDURE [dbo].[VirtualizationProductNameBind]
	@ProductName		nvarchar(256)
AS
	DECLARE	@ID	int

	SELECT	@ID = VirtualizationProductNameID
	FROM	[dbo].[VirtualizationProductName]
	WHERE	ProductName = @ProductName

	IF @ID IS NULL
		EXEC @ID = VirtualizationProductNameAdd @ProductName

	RETURN @ID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[VirtualizationProductNameSchema]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[VirtualizationProductNameSchema]
GO
CREATE PROCEDURE [dbo].[VirtualizationProductNameSchema]
AS
	SELECT
	'IF OBJECT_ID(''tempdb..#VirtualizationProductName'') IS NULL' + CAST(0x0A AS CHAR(1)) +
	'	CREATE TABLE #VirtualizationProductName (' + CAST(0x0A AS CHAR(1)) +
	'		VirtualizationProductNameID int NULL,' + CAST(0x0A AS CHAR(1)) +
	'		ProductName		nvarchar(256) COLLATE database_default NOT NULL' + CAST(0x0A AS CHAR(1)) +
	'	)' + CAST(0x0A AS CHAR(1)) +
	'ELSE' + CAST(0x0A AS CHAR(1)) +
	'	DELETE FROM #VirtualizationProductName' + CAST(0x0A AS CHAR(1)) +
	'' AS SQL
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[VirtualizationProductNameTempAdd]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[VirtualizationProductNameTempAdd]
GO
CREATE PROCEDURE dbo.[VirtualizationProductNameTempAdd]
	@VirtualizationProductNameID int,
	@ProductName		nvarchar(256)
AS
	INSERT INTO #VirtualizationProductName (
		VirtualizationProductNameID,
		ProductName
	)
	VALUES (
		@VirtualizationProductNameID,
		@ProductName
	)
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[VirtualizationProductNameAddBatch]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[VirtualizationProductNameAddBatch]
GO
CREATE PROCEDURE dbo.[VirtualizationProductNameAddBatch]
AS
	DECLARE @count int
	INSERT dbo.VirtualizationProductName (
		ProductName
	)
		SELECT	ProductName
		FROM #VirtualizationProductName
	SET @count = @@ROWCOUNT
	DROP TABLE #VirtualizationProductName	-- Drop temporary table
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[VirtualizationProductNameUpdateByID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[VirtualizationProductNameUpdateByID]
GO
CREATE PROCEDURE [dbo].[VirtualizationProductNameUpdateByID]
	@VirtualizationProductNameID int,
	@ProductName		nvarchar(256)
AS
	DECLARE	@ID	int
	SET @ID = 0

	UPDATE	[dbo].[VirtualizationProductName]
	SET	@ID = VirtualizationProductNameID,
		ProductName = @ProductName
	WHERE	VirtualizationProductNameID = @VirtualizationProductNameID
	RETURN @ID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[VirtualizationProductNameUpdateBatchByID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[VirtualizationProductNameUpdateBatchByID]
GO
CREATE PROCEDURE dbo.[VirtualizationProductNameUpdateBatchByID]
AS
	DECLARE @count int

	CREATE INDEX [TempVirtualizationProductNameID]
		ON #VirtualizationProductName (VirtualizationProductNameID)

	UPDATE	[dbo].[VirtualizationProductName]
	SET	ProductName = t.ProductName
	FROM	#VirtualizationProductName AS t
	WHERE	VirtualizationProductName.VirtualizationProductNameID = t.VirtualizationProductNameID
	SET @count = @@ROWCOUNT
	DROP TABLE #VirtualizationProductName	-- Drop the temporary table
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[VirtualizationProductNamePutByProductName]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[VirtualizationProductNamePutByProductName]
GO
CREATE PROCEDURE [dbo].[VirtualizationProductNamePutByProductName]
	@ProductName		nvarchar(256)
AS
	DECLARE @ID	int

	SELECT	@ID = VirtualizationProductNameID
	FROM	VirtualizationProductName
	WHERE	ProductName = @ProductName

	IF @ID IS NULL
		EXEC @ID = VirtualizationProductNameAdd @ProductName

	RETURN @ID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[VirtualizationProductNamePutBatchByProductName]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[VirtualizationProductNamePutBatchByProductName]
GO
CREATE PROCEDURE [dbo].[VirtualizationProductNamePutBatchByProductName]
AS
	DECLARE @count AS int
	SET @count = 0

	CREATE INDEX [TempVirtualizationProductNameProductName]
		ON #VirtualizationProductName (ProductName)

	BEGIN TRANSACTION

	INSERT [dbo].[VirtualizationProductName] (
		ProductName
	)
		SELECT	ProductName
		FROM	#VirtualizationProductName AS t
		WHERE NOT EXISTS(	-- Current record doesn't exist
			SELECT * FROM [dbo].[VirtualizationProductName]
			WHERE	VirtualizationProductName.ProductName = t.ProductName
		)
	SET @count = @count + @@ROWCOUNT
	DROP TABLE #VirtualizationProductName	-- Drop the temporary table
	COMMIT WORK
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[VirtualizationProductNameRemoveBatch]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[VirtualizationProductNameRemoveBatch]
GO

CREATE PROCEDURE [dbo].[VirtualizationProductNameRemoveBatch]
AS

	CREATE INDEX [TempVirtualizationProductNameVirtualizationProductNameRemoveBatch]
		ON #VirtualizationProductName (VirtualizationProductNameID)	

	-- Delete records from VirtualizationProductName identified by fields of [TempVirtualizationProductNameVirtualizationProductNameRemoveBatch]
	DELETE [dbo].[VirtualizationProductName]
	WHERE EXISTS(
			SELECT * FROM #VirtualizationProductName AS t
			WHERE	VirtualizationProductName.VirtualizationProductNameID = t.VirtualizationProductNameID
		)
	DROP TABLE #VirtualizationProductName      -- Drop the temporary table
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[VirtualizationProductNameRemoveByID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[VirtualizationProductNameRemoveByID]
GO
CREATE PROCEDURE [dbo].[VirtualizationProductNameRemoveByID]
	@VirtualizationProductNameID int
AS
	-- VirtualizationProductName deletes may fail due to non-cascading FKs:
	--	NetworkDeviceVirtualizationInfo by FK_NetworkDeviceVirtualizationInfo_VirtualizationProductName
	DELETE	[dbo].[VirtualizationProductName]
	WHERE	VirtualizationProductNameID = @VirtualizationProductNameID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[VirtualizationProductNameRemoveByProductName]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[VirtualizationProductNameRemoveByProductName]
GO
CREATE PROCEDURE [dbo].[VirtualizationProductNameRemoveByProductName]
	@ProductName		nvarchar(256)
AS
	-- VirtualizationProductName deletes may fail due to non-cascading FKs:
	--	NetworkDeviceVirtualizationInfo by FK_NetworkDeviceVirtualizationInfo_VirtualizationProductName
	DELETE	[dbo].[VirtualizationProductName]
	WHERE	ProductName = @ProductName
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[VirtualizationProductNameRemoveAll]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[VirtualizationProductNameRemoveAll]
GO
CREATE PROCEDURE [dbo].[VirtualizationProductNameRemoveAll]
	
AS
	DELETE	[dbo].[VirtualizationProductName]
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[NetworkDeviceVirtualizationInfoGetByDeviceID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[NetworkDeviceVirtualizationInfoGetByDeviceID]
GO
CREATE PROCEDURE [dbo].[NetworkDeviceVirtualizationInfoGetByDeviceID]
	@DeviceID		int
AS
	SELECT	DeviceID,
		Protocol,
		Port,
		APIType,
		APIVersion,
		ProductNameID,
		ProductVersion
	FROM	[dbo].[NetworkDeviceVirtualizationInfo]
	WHERE	DeviceID = @DeviceID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[NetworkDeviceVirtualizationInfoGetAll]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[NetworkDeviceVirtualizationInfoGetAll]
GO
CREATE PROCEDURE [dbo].[NetworkDeviceVirtualizationInfoGetAll]
AS
	SELECT	DeviceID,
		Protocol,
		Port,
		APIType,
		APIVersion,
		ProductNameID,
		ProductVersion
	FROM	[dbo].[NetworkDeviceVirtualizationInfo]
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[NetworkDeviceVirtualizationInfoAdd]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[NetworkDeviceVirtualizationInfoAdd]
GO
CREATE PROCEDURE [dbo].[NetworkDeviceVirtualizationInfoAdd]
	@DeviceID		int,
	@Protocol		varchar(16) = NULL,
	@Port			int,
	@APIType		varchar(32) = NULL,
	@APIVersion		varchar(16) = NULL,
	@ProductNameID		int,
	@ProductVersion		varchar(16) = NULL
AS
	INSERT INTO  dbo.NetworkDeviceVirtualizationInfo (
		DeviceID,
		Protocol,
		Port,
		APIType,
		APIVersion,
		ProductNameID,
		ProductVersion
	)
	VALUES (
		@DeviceID,
		@Protocol,
		@Port,
		@APIType,
		@APIVersion,
		@ProductNameID,
		@ProductVersion
	)
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[NetworkDeviceVirtualizationInfoSchema]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[NetworkDeviceVirtualizationInfoSchema]
GO
CREATE PROCEDURE [dbo].[NetworkDeviceVirtualizationInfoSchema]
AS
	SELECT
	'IF OBJECT_ID(''tempdb..#NetworkDeviceVirtualizationInfo'') IS NULL' + CAST(0x0A AS CHAR(1)) +
	'	CREATE TABLE #NetworkDeviceVirtualizationInfo (' + CAST(0x0A AS CHAR(1)) +
	'		DeviceID		int NOT NULL,' + CAST(0x0A AS CHAR(1)) +
	'		Protocol		varchar(16) COLLATE database_default NULL,' + CAST(0x0A AS CHAR(1)) +
	'		Port			int NOT NULL,' + CAST(0x0A AS CHAR(1)) +
	'		APIType			varchar(32) COLLATE database_default NULL,' + CAST(0x0A AS CHAR(1)) +
	'		APIVersion		varchar(16) COLLATE database_default NULL,' + CAST(0x0A AS CHAR(1)) +
	'		ProductNameID		int NOT NULL,' + CAST(0x0A AS CHAR(1)) +
	'		ProductVersion		varchar(16) COLLATE database_default NULL' + CAST(0x0A AS CHAR(1)) +
	'	)' + CAST(0x0A AS CHAR(1)) +
	'ELSE' + CAST(0x0A AS CHAR(1)) +
	'	DELETE FROM #NetworkDeviceVirtualizationInfo' + CAST(0x0A AS CHAR(1)) +
	'' AS SQL
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[NetworkDeviceVirtualizationInfoTempAdd]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[NetworkDeviceVirtualizationInfoTempAdd]
GO
CREATE PROCEDURE dbo.[NetworkDeviceVirtualizationInfoTempAdd]
	@DeviceID		int,
	@Protocol		varchar(16) = NULL,
	@Port			int,
	@APIType		varchar(32) = NULL,
	@APIVersion		varchar(16) = NULL,
	@ProductNameID		int,
	@ProductVersion		varchar(16) = NULL
AS
	INSERT INTO #NetworkDeviceVirtualizationInfo (
		DeviceID,
		Protocol,
		Port,
		APIType,
		APIVersion,
		ProductNameID,
		ProductVersion
	)
	VALUES (
		@DeviceID,
		@Protocol,
		@Port,
		@APIType,
		@APIVersion,
		@ProductNameID,
		@ProductVersion
	)
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[NetworkDeviceVirtualizationInfoAddBatch]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[NetworkDeviceVirtualizationInfoAddBatch]
GO
CREATE PROCEDURE dbo.[NetworkDeviceVirtualizationInfoAddBatch]
AS
	DECLARE @count int
	INSERT dbo.NetworkDeviceVirtualizationInfo (
		DeviceID,
		Protocol,
		Port,
		APIType,
		APIVersion,
		ProductNameID,
		ProductVersion
	)
		SELECT	DeviceID,
			Protocol,
			Port,
			APIType,
			APIVersion,
			ProductNameID,
			ProductVersion
		FROM #NetworkDeviceVirtualizationInfo
	SET @count = @@ROWCOUNT
	DROP TABLE #NetworkDeviceVirtualizationInfo	-- Drop temporary table
	RETURN @count
GO

/*
Add new NetworkDeviceVirtualizationInfo bound to
	VirtualizationProductName using ProductName
	with DeviceID, Protocol, Port, APIType, APIVersion, ProductVersion
*/

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[NetworkDeviceVirtualizationInfoUpdateByDeviceID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[NetworkDeviceVirtualizationInfoUpdateByDeviceID]
GO
CREATE PROCEDURE [dbo].[NetworkDeviceVirtualizationInfoUpdateByDeviceID]
	@DeviceID		int,
	@Protocol		varchar(16) = NULL,
	@Port			int,
	@APIType		varchar(32) = NULL,
	@APIVersion		varchar(16) = NULL,
	@ProductNameID		int,
	@ProductVersion		varchar(16) = NULL
AS
	UPDATE	[dbo].[NetworkDeviceVirtualizationInfo]
	SET	Protocol = @Protocol,
		Port = @Port,
		APIType = @APIType,
		APIVersion = @APIVersion,
		ProductNameID = @ProductNameID,
		ProductVersion = @ProductVersion
	WHERE	DeviceID = @DeviceID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[NetworkDeviceVirtualizationInfoUpdateBatchByDeviceID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[NetworkDeviceVirtualizationInfoUpdateBatchByDeviceID]
GO
CREATE PROCEDURE dbo.[NetworkDeviceVirtualizationInfoUpdateBatchByDeviceID]
AS
	DECLARE @count int

	CREATE INDEX [TempNetworkDeviceVirtualizationInfoDeviceID]
		ON #NetworkDeviceVirtualizationInfo (DeviceID)

	UPDATE	[dbo].[NetworkDeviceVirtualizationInfo]
	SET	Protocol = t.Protocol,
		Port = t.Port,
		APIType = t.APIType,
		APIVersion = t.APIVersion,
		ProductNameID = t.ProductNameID,
		ProductVersion = t.ProductVersion
	FROM	#NetworkDeviceVirtualizationInfo AS t
	WHERE	NetworkDeviceVirtualizationInfo.DeviceID = t.DeviceID
	SET @count = @@ROWCOUNT
	DROP TABLE #NetworkDeviceVirtualizationInfo	-- Drop the temporary table
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[NetworkDeviceVirtualizationInfoPutByDeviceID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[NetworkDeviceVirtualizationInfoPutByDeviceID]
GO
CREATE PROCEDURE [dbo].[NetworkDeviceVirtualizationInfoPutByDeviceID]
	@DeviceID		int,
	@Protocol		varchar(16) = NULL,
	@Port			int,
	@APIType		varchar(32) = NULL,
	@APIVersion		varchar(16) = NULL,
	@ProductNameID		int,
	@ProductVersion		varchar(16) = NULL
AS
	IF NOT EXISTS(
		SELECT	1
		FROM	dbo.NetworkDeviceVirtualizationInfo
		WHERE	DeviceID = @DeviceID
	)
		EXEC NetworkDeviceVirtualizationInfoAdd @DeviceID,
			@Protocol,
			@Port,
			@APIType,
			@APIVersion,
			@ProductNameID,
			@ProductVersion
	ELSE
		EXEC NetworkDeviceVirtualizationInfoUpdateByDeviceID @DeviceID,
			@Protocol,
			@Port,
			@APIType,
			@APIVersion,
			@ProductNameID,
			@ProductVersion
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[NetworkDeviceVirtualizationInfoPutBatchByDeviceID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[NetworkDeviceVirtualizationInfoPutBatchByDeviceID]
GO
CREATE PROCEDURE [dbo].[NetworkDeviceVirtualizationInfoPutBatchByDeviceID]
AS
	DECLARE @count AS int
	SET @count = 0

	CREATE INDEX [TempNetworkDeviceVirtualizationInfoDeviceID]
		ON #NetworkDeviceVirtualizationInfo (DeviceID)

	BEGIN TRANSACTION
	UPDATE [dbo].[NetworkDeviceVirtualizationInfo]
		SET	Protocol = t.Protocol,
			Port = t.Port,
			APIType = t.APIType,
			APIVersion = t.APIVersion,
			ProductNameID = t.ProductNameID,
			ProductVersion = t.ProductVersion
		FROM	#NetworkDeviceVirtualizationInfo AS t
		WHERE	NetworkDeviceVirtualizationInfo.DeviceID = t.DeviceID
	SET @count = @@ROWCOUNT

	INSERT [dbo].[NetworkDeviceVirtualizationInfo] (
		DeviceID,
		Protocol,
		Port,
		APIType,
		APIVersion,
		ProductNameID,
		ProductVersion
	)
		SELECT	DeviceID,
			Protocol,
			Port,
			APIType,
			APIVersion,
			ProductNameID,
			ProductVersion
		FROM	#NetworkDeviceVirtualizationInfo AS t
		WHERE NOT EXISTS(	-- Current record doesn't exist
			SELECT * FROM [dbo].[NetworkDeviceVirtualizationInfo]
			WHERE	NetworkDeviceVirtualizationInfo.DeviceID = t.DeviceID
		)
	SET @count = @count + @@ROWCOUNT
	DROP TABLE #NetworkDeviceVirtualizationInfo	-- Drop the temporary table
	COMMIT WORK
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[NetworkDeviceVirtualizationInfoRemoveBatch]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[NetworkDeviceVirtualizationInfoRemoveBatch]
GO

CREATE PROCEDURE [dbo].[NetworkDeviceVirtualizationInfoRemoveBatch]
AS

	CREATE INDEX [TempNetworkDeviceVirtualizationInfoNetworkDeviceVirtualizationInfoRemoveBatch]
		ON #NetworkDeviceVirtualizationInfo (DeviceID)	

	-- Delete records from NetworkDeviceVirtualizationInfo identified by fields of [TempNetworkDeviceVirtualizationInfoNetworkDeviceVirtualizationInfoRemoveBatch]
	DELETE [dbo].[NetworkDeviceVirtualizationInfo]
	WHERE EXISTS(
			SELECT * FROM #NetworkDeviceVirtualizationInfo AS t
			WHERE	NetworkDeviceVirtualizationInfo.DeviceID = t.DeviceID
		)
	DROP TABLE #NetworkDeviceVirtualizationInfo      -- Drop the temporary table
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[NetworkDeviceVirtualizationInfoRemoveByDeviceID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[NetworkDeviceVirtualizationInfoRemoveByDeviceID]
GO
CREATE PROCEDURE [dbo].[NetworkDeviceVirtualizationInfoRemoveByDeviceID]
	@DeviceID		int
AS
	DELETE	[dbo].[NetworkDeviceVirtualizationInfo]
	WHERE	DeviceID = @DeviceID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[NetworkDeviceVirtualizationInfoRemoveAll]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[NetworkDeviceVirtualizationInfoRemoveAll]
GO
CREATE PROCEDURE [dbo].[NetworkDeviceVirtualizationInfoRemoveAll]
	
AS
	DELETE	[dbo].[NetworkDeviceVirtualizationInfo]
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[NetworkDeviceParentGetByDeviceIDParentDeviceID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[NetworkDeviceParentGetByDeviceIDParentDeviceID]
GO
CREATE PROCEDURE [dbo].[NetworkDeviceParentGetByDeviceIDParentDeviceID]
	@DeviceID		int,
	@ParentDeviceID		int
AS
	SELECT	DeviceID,
		ParentDeviceID
	FROM	[dbo].[NetworkDeviceParent]
	WHERE	DeviceID = @DeviceID
	  AND	ParentDeviceID = @ParentDeviceID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[NetworkDeviceParentGetAllByDeviceID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[NetworkDeviceParentGetAllByDeviceID]
GO
CREATE PROCEDURE [dbo].[NetworkDeviceParentGetAllByDeviceID]
	@DeviceID		int
AS
	SELECT	DeviceID,
		ParentDeviceID
	FROM	[dbo].[NetworkDeviceParent]
	WHERE	DeviceID = @DeviceID
	ORDER BY ParentDeviceID
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[NetworkDeviceParentGetAll]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[NetworkDeviceParentGetAll]
GO
CREATE PROCEDURE [dbo].[NetworkDeviceParentGetAll]
AS
	SELECT	DeviceID,
		ParentDeviceID
	FROM	[dbo].[NetworkDeviceParent]
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[NetworkDeviceParentAdd]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[NetworkDeviceParentAdd]
GO
CREATE PROCEDURE [dbo].[NetworkDeviceParentAdd]
	@DeviceID		int,
	@ParentDeviceID		int
AS
	INSERT INTO  dbo.NetworkDeviceParent (
		DeviceID,
		ParentDeviceID
	)
	VALUES (
		@DeviceID,
		@ParentDeviceID
	)
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[NetworkDeviceParentSchema]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[NetworkDeviceParentSchema]
GO
CREATE PROCEDURE [dbo].[NetworkDeviceParentSchema]
AS
	SELECT
	'IF OBJECT_ID(''tempdb..#NetworkDeviceParent'') IS NULL' + CAST(0x0A AS CHAR(1)) +
	'	CREATE TABLE #NetworkDeviceParent (' + CAST(0x0A AS CHAR(1)) +
	'		DeviceID		int NOT NULL,' + CAST(0x0A AS CHAR(1)) +
	'		ParentDeviceID		int NOT NULL' + CAST(0x0A AS CHAR(1)) +
	'	)' + CAST(0x0A AS CHAR(1)) +
	'ELSE' + CAST(0x0A AS CHAR(1)) +
	'	DELETE FROM #NetworkDeviceParent' + CAST(0x0A AS CHAR(1)) +
	'' AS SQL
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[NetworkDeviceParentTempAdd]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[NetworkDeviceParentTempAdd]
GO
CREATE PROCEDURE dbo.[NetworkDeviceParentTempAdd]
	@DeviceID		int,
	@ParentDeviceID		int
AS
	INSERT INTO #NetworkDeviceParent (
		DeviceID,
		ParentDeviceID
	)
	VALUES (
		@DeviceID,
		@ParentDeviceID
	)
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[NetworkDeviceParentAddBatch]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[NetworkDeviceParentAddBatch]
GO
CREATE PROCEDURE dbo.[NetworkDeviceParentAddBatch]
AS
	DECLARE @count int
	INSERT dbo.NetworkDeviceParent (
		DeviceID,
		ParentDeviceID
	)
		SELECT	DeviceID,
			ParentDeviceID
		FROM #NetworkDeviceParent
	SET @count = @@ROWCOUNT
	DROP TABLE #NetworkDeviceParent	-- Drop temporary table
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[NetworkDeviceParentPutByDeviceIDParentDeviceID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[NetworkDeviceParentPutByDeviceIDParentDeviceID]
GO
CREATE PROCEDURE [dbo].[NetworkDeviceParentPutByDeviceIDParentDeviceID]
	@DeviceID		int,
	@ParentDeviceID		int
AS
	IF NOT EXISTS(
		SELECT	1
		FROM	dbo.NetworkDeviceParent
		WHERE	DeviceID = @DeviceID
		  AND	ParentDeviceID = @ParentDeviceID
	)
		EXEC NetworkDeviceParentAdd @DeviceID,
			@ParentDeviceID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[NetworkDeviceParentPutBatchByDeviceIDParentDeviceID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[NetworkDeviceParentPutBatchByDeviceIDParentDeviceID]
GO
CREATE PROCEDURE [dbo].[NetworkDeviceParentPutBatchByDeviceIDParentDeviceID]
AS
	DECLARE @count AS int
	SET @count = 0

	CREATE INDEX [TempNetworkDeviceParentDeviceIDParentDeviceID]
		ON #NetworkDeviceParent (DeviceID, ParentDeviceID)

	BEGIN TRANSACTION

	INSERT [dbo].[NetworkDeviceParent] (
		DeviceID,
		ParentDeviceID
	)
		SELECT	DeviceID,
			ParentDeviceID
		FROM	#NetworkDeviceParent AS t
		WHERE NOT EXISTS(	-- Current record doesn't exist
			SELECT * FROM [dbo].[NetworkDeviceParent]
			WHERE	NetworkDeviceParent.DeviceID = t.DeviceID
			  AND	NetworkDeviceParent.ParentDeviceID = t.ParentDeviceID
		)
	SET @count = @count + @@ROWCOUNT
	DROP TABLE #NetworkDeviceParent	-- Drop the temporary table
	COMMIT WORK
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[NetworkDeviceParentRemoveBatch]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[NetworkDeviceParentRemoveBatch]
GO

CREATE PROCEDURE [dbo].[NetworkDeviceParentRemoveBatch]
AS

	CREATE INDEX [TempNetworkDeviceParentNetworkDeviceParentRemoveBatch]
		ON #NetworkDeviceParent (DeviceID, ParentDeviceID)	

	-- Delete records from NetworkDeviceParent identified by fields of [TempNetworkDeviceParentNetworkDeviceParentRemoveBatch]
	DELETE [dbo].[NetworkDeviceParent]
	WHERE EXISTS(
			SELECT * FROM #NetworkDeviceParent AS t
			WHERE	NetworkDeviceParent.DeviceID = t.DeviceID
			  AND	NetworkDeviceParent.ParentDeviceID = t.ParentDeviceID
		)
	DROP TABLE #NetworkDeviceParent      -- Drop the temporary table
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[NetworkDeviceParentRemoveByDeviceIDParentDeviceID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[NetworkDeviceParentRemoveByDeviceIDParentDeviceID]
GO
CREATE PROCEDURE [dbo].[NetworkDeviceParentRemoveByDeviceIDParentDeviceID]
	@DeviceID		int,
	@ParentDeviceID		int
AS
	DELETE	[dbo].[NetworkDeviceParent]
	WHERE	DeviceID = @DeviceID
	  AND	ParentDeviceID = @ParentDeviceID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[NetworkDeviceParentRemoveAllByDeviceID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[NetworkDeviceParentRemoveAllByDeviceID]
GO
CREATE PROCEDURE [dbo].[NetworkDeviceParentRemoveAllByDeviceID]
	@DeviceID		int
AS
	DELETE	[dbo].[NetworkDeviceParent]
	WHERE	DeviceID = @DeviceID
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[NetworkDeviceParentRemoveAll]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[NetworkDeviceParentRemoveAll]
GO
CREATE PROCEDURE [dbo].[NetworkDeviceParentRemoveAll]
	
AS
	DELETE	[dbo].[NetworkDeviceParent]
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[AdministrationAccountGetByID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[AdministrationAccountGetByID]
GO
CREATE PROCEDURE [dbo].[AdministrationAccountGetByID]
	@AccountID		int
AS
	SELECT	AccountID,
		AccountName
	FROM	[dbo].[AdministrationAccount]
	WHERE	AccountID = @AccountID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[AdministrationAccountGetByAccountName]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[AdministrationAccountGetByAccountName]
GO
CREATE PROCEDURE [dbo].[AdministrationAccountGetByAccountName]
	@AccountName		nvarchar(256)
AS
	SELECT	AccountID,
		AccountName
	FROM	[dbo].[AdministrationAccount]
	WHERE	AccountName = @AccountName
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[AdministrationAccountGetAll]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[AdministrationAccountGetAll]
GO
CREATE PROCEDURE [dbo].[AdministrationAccountGetAll]
AS
	SELECT	AccountID,
		AccountName
	FROM	[dbo].[AdministrationAccount]
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[AdministrationAccountAdd]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[AdministrationAccountAdd]
GO
CREATE PROCEDURE [dbo].[AdministrationAccountAdd]
	@AccountName		nvarchar(256)
AS
	INSERT INTO  dbo.AdministrationAccount (
		AccountName
	)
	VALUES (
		@AccountName
	)
	RETURN SCOPE_IDENTITY()
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[AdministrationAccountBind]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[AdministrationAccountBind]
GO
CREATE PROCEDURE [dbo].[AdministrationAccountBind]
	@AccountName		nvarchar(256)
AS
	DECLARE	@ID	int

	SELECT	@ID = AccountID
	FROM	[dbo].[AdministrationAccount]
	WHERE	AccountName = @AccountName

	IF @ID IS NULL
		EXEC @ID = AdministrationAccountAdd @AccountName

	RETURN @ID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[AdministrationAccountSchema]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[AdministrationAccountSchema]
GO
CREATE PROCEDURE [dbo].[AdministrationAccountSchema]
AS
	SELECT
	'IF OBJECT_ID(''tempdb..#AdministrationAccount'') IS NULL' + CAST(0x0A AS CHAR(1)) +
	'	CREATE TABLE #AdministrationAccount (' + CAST(0x0A AS CHAR(1)) +
	'		AccountID		int NULL,' + CAST(0x0A AS CHAR(1)) +
	'		AccountName		nvarchar(256) COLLATE database_default NOT NULL' + CAST(0x0A AS CHAR(1)) +
	'	)' + CAST(0x0A AS CHAR(1)) +
	'ELSE' + CAST(0x0A AS CHAR(1)) +
	'	DELETE FROM #AdministrationAccount' + CAST(0x0A AS CHAR(1)) +
	'' AS SQL
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[AdministrationAccountTempAdd]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[AdministrationAccountTempAdd]
GO
CREATE PROCEDURE dbo.[AdministrationAccountTempAdd]
	@AccountID		int,
	@AccountName		nvarchar(256)
AS
	INSERT INTO #AdministrationAccount (
		AccountID,
		AccountName
	)
	VALUES (
		@AccountID,
		@AccountName
	)
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[AdministrationAccountAddBatch]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[AdministrationAccountAddBatch]
GO
CREATE PROCEDURE dbo.[AdministrationAccountAddBatch]
AS
	DECLARE @count int
	INSERT dbo.AdministrationAccount (
		AccountName
	)
		SELECT	AccountName
		FROM #AdministrationAccount
	SET @count = @@ROWCOUNT
	DROP TABLE #AdministrationAccount	-- Drop temporary table
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[AdministrationAccountUpdateByID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[AdministrationAccountUpdateByID]
GO
CREATE PROCEDURE [dbo].[AdministrationAccountUpdateByID]
	@AccountID		int,
	@AccountName		nvarchar(256)
AS
	DECLARE	@ID	int
	SET @ID = 0

	UPDATE	[dbo].[AdministrationAccount]
	SET	@ID = AccountID,
		AccountName = @AccountName
	WHERE	AccountID = @AccountID
	RETURN @ID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[AdministrationAccountUpdateBatchByID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[AdministrationAccountUpdateBatchByID]
GO
CREATE PROCEDURE dbo.[AdministrationAccountUpdateBatchByID]
AS
	DECLARE @count int

	CREATE INDEX [TempAdministrationAccountID]
		ON #AdministrationAccount (AccountID)

	UPDATE	[dbo].[AdministrationAccount]
	SET	AccountName = t.AccountName
	FROM	#AdministrationAccount AS t
	WHERE	AdministrationAccount.AccountID = t.AccountID
	SET @count = @@ROWCOUNT
	DROP TABLE #AdministrationAccount	-- Drop the temporary table
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[AdministrationAccountPutByAccountName]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[AdministrationAccountPutByAccountName]
GO
CREATE PROCEDURE [dbo].[AdministrationAccountPutByAccountName]
	@AccountName		nvarchar(256)
AS
	DECLARE @ID	int

	SELECT	@ID = AccountID
	FROM	AdministrationAccount
	WHERE	AccountName = @AccountName

	IF @ID IS NULL
		EXEC @ID = AdministrationAccountAdd @AccountName

	RETURN @ID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[AdministrationAccountPutBatchByAccountName]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[AdministrationAccountPutBatchByAccountName]
GO
CREATE PROCEDURE [dbo].[AdministrationAccountPutBatchByAccountName]
AS
	DECLARE @count AS int
	SET @count = 0

	CREATE INDEX [TempAdministrationAccountAccountName]
		ON #AdministrationAccount (AccountName)

	BEGIN TRANSACTION

	INSERT [dbo].[AdministrationAccount] (
		AccountName
	)
		SELECT	AccountName
		FROM	#AdministrationAccount AS t
		WHERE NOT EXISTS(	-- Current record doesn't exist
			SELECT * FROM [dbo].[AdministrationAccount]
			WHERE	AdministrationAccount.AccountName = t.AccountName
		)
	SET @count = @count + @@ROWCOUNT
	DROP TABLE #AdministrationAccount	-- Drop the temporary table
	COMMIT WORK
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[AdministrationAccountRemoveBatch]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[AdministrationAccountRemoveBatch]
GO

CREATE PROCEDURE [dbo].[AdministrationAccountRemoveBatch]
AS

	CREATE INDEX [TempAdministrationAccountAdministrationAccountRemoveBatch]
		ON #AdministrationAccount (AccountID)	

	-- Delete records from AdministrationAccount identified by fields of [TempAdministrationAccountAdministrationAccountRemoveBatch]
	DELETE [dbo].[AdministrationAccount]
	WHERE EXISTS(
			SELECT * FROM #AdministrationAccount AS t
			WHERE	AdministrationAccount.AccountID = t.AccountID
		)
	DROP TABLE #AdministrationAccount      -- Drop the temporary table
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[AdministrationAccountRemoveByAccountName]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[AdministrationAccountRemoveByAccountName]
GO
CREATE PROCEDURE [dbo].[AdministrationAccountRemoveByAccountName]
	@AccountName		nvarchar(256)
AS
	-- AdministrationAccount deletes cascade to:
	--	DistributionServerAdministrationAccount by FK_DSAdministrationAccount_AdministrationAccount
	--	NetworkDeviceDiscoveredBy by FK_NetworkDeviceDiscoveredBy_Account
	-- AdministrationAccount deletes may fail due to non-cascading FKs:
	--	NetworkDeviceDiscoveredBy by FK_NetworkDeviceDiscoveredBy_AccountOverride
	DELETE	[dbo].[AdministrationAccount]
	WHERE	AccountName = @AccountName
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[AdministrationAccountRemoveAll]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[AdministrationAccountRemoveAll]
GO
CREATE PROCEDURE [dbo].[AdministrationAccountRemoveAll]
	
AS
	DELETE	[dbo].[AdministrationAccount]
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[DistributionServerAdministrationAccountGetByServerUIDAccountID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[DistributionServerAdministrationAccountGetByServerUIDAccountID]
GO
CREATE PROCEDURE [dbo].[DistributionServerAdministrationAccountGetByServerUIDAccountID]
	@ServerUID		binary(16),
	@AccountID		int
AS
	SELECT	AccountID,
		ServerUID
	FROM	[dbo].[DistributionServerAdministrationAccount]
	WHERE	ServerUID = @ServerUID
	  AND	AccountID = @AccountID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[DistributionServerAdministrationAccountGetAll]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[DistributionServerAdministrationAccountGetAll]
GO
CREATE PROCEDURE [dbo].[DistributionServerAdministrationAccountGetAll]
AS
	SELECT	AccountID,
		ServerUID
	FROM	[dbo].[DistributionServerAdministrationAccount]
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[DistributionServerAdministrationAccountAdd]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[DistributionServerAdministrationAccountAdd]
GO
CREATE PROCEDURE [dbo].[DistributionServerAdministrationAccountAdd]
	@AccountID		int,
	@ServerUID		binary(16)
AS
	INSERT INTO  dbo.DistributionServerAdministrationAccount (
		AccountID,
		ServerUID
	)
	VALUES (
		@AccountID,
		@ServerUID
	)
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[DistributionServerAdministrationAccountSchema]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[DistributionServerAdministrationAccountSchema]
GO
CREATE PROCEDURE [dbo].[DistributionServerAdministrationAccountSchema]
AS
	SELECT
	'IF OBJECT_ID(''tempdb..#DistributionServerAdministrationAccount'') IS NULL' + CAST(0x0A AS CHAR(1)) +
	'	CREATE TABLE #DistributionServerAdministrationAccount (' + CAST(0x0A AS CHAR(1)) +
	'		AccountID		int NOT NULL,' + CAST(0x0A AS CHAR(1)) +
	'		ServerUID		binary(16) NOT NULL' + CAST(0x0A AS CHAR(1)) +
	'	)' + CAST(0x0A AS CHAR(1)) +
	'ELSE' + CAST(0x0A AS CHAR(1)) +
	'	DELETE FROM #DistributionServerAdministrationAccount' + CAST(0x0A AS CHAR(1)) +
	'' AS SQL
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[DistributionServerAdministrationAccountTempAdd]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[DistributionServerAdministrationAccountTempAdd]
GO
CREATE PROCEDURE dbo.[DistributionServerAdministrationAccountTempAdd]
	@AccountID		int,
	@ServerUID		binary(16)
AS
	INSERT INTO #DistributionServerAdministrationAccount (
		AccountID,
		ServerUID
	)
	VALUES (
		@AccountID,
		@ServerUID
	)
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[DistributionServerAdministrationAccountAddBatch]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[DistributionServerAdministrationAccountAddBatch]
GO
CREATE PROCEDURE dbo.[DistributionServerAdministrationAccountAddBatch]
AS
	DECLARE @count int
	INSERT dbo.DistributionServerAdministrationAccount (
		AccountID,
		ServerUID
	)
		SELECT	AccountID,
			ServerUID
		FROM #DistributionServerAdministrationAccount
	SET @count = @@ROWCOUNT
	DROP TABLE #DistributionServerAdministrationAccount	-- Drop temporary table
	RETURN @count
GO

/*
Add new DistributionServerAdministrationAccount bound to
	AdministrationAccount using AccountName
	with ServerUID
*/

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[DistributionServerAdministrationAccountPutByServerUIDAccountID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[DistributionServerAdministrationAccountPutByServerUIDAccountID]
GO
CREATE PROCEDURE [dbo].[DistributionServerAdministrationAccountPutByServerUIDAccountID]
	@ServerUID		binary(16),
	@AccountID		int
AS
	IF NOT EXISTS(
		SELECT	1
		FROM	dbo.DistributionServerAdministrationAccount
		WHERE	ServerUID = @ServerUID
		  AND	AccountID = @AccountID
	)
		EXEC DistributionServerAdministrationAccountAdd @AccountID,
			@ServerUID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[DistributionServerAdministrationAccountPutBatchByServerUIDAccountID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[DistributionServerAdministrationAccountPutBatchByServerUIDAccountID]
GO
CREATE PROCEDURE [dbo].[DistributionServerAdministrationAccountPutBatchByServerUIDAccountID]
AS
	DECLARE @count AS int
	SET @count = 0

	CREATE INDEX [TempDistributionServerAdministrationAccountServerUIDAccountID]
		ON #DistributionServerAdministrationAccount (ServerUID, AccountID)

	BEGIN TRANSACTION

	INSERT [dbo].[DistributionServerAdministrationAccount] (
		AccountID,
		ServerUID
	)
		SELECT	AccountID,
			ServerUID
		FROM	#DistributionServerAdministrationAccount AS t
		WHERE NOT EXISTS(	-- Current record doesn't exist
			SELECT * FROM [dbo].[DistributionServerAdministrationAccount]
			WHERE	DistributionServerAdministrationAccount.ServerUID = t.ServerUID
			  AND	DistributionServerAdministrationAccount.AccountID = t.AccountID
		)
	SET @count = @count + @@ROWCOUNT
	DROP TABLE #DistributionServerAdministrationAccount	-- Drop the temporary table
	COMMIT WORK
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[DistributionServerAdministrationAccountRemoveBatch]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[DistributionServerAdministrationAccountRemoveBatch]
GO

CREATE PROCEDURE [dbo].[DistributionServerAdministrationAccountRemoveBatch]
AS

	CREATE INDEX [TempDistributionServerAdministrationAccountDistributionServerAdministrationAccountRemoveBatch]
		ON #DistributionServerAdministrationAccount (ServerUID, AccountID)	

	-- Delete records from DistributionServerAdministrationAccount identified by fields of [TempDistributionServerAdministrationAccountDistributionServerAdministrationAccountRemoveBatch]
	DELETE [dbo].[DistributionServerAdministrationAccount]
	WHERE EXISTS(
			SELECT * FROM #DistributionServerAdministrationAccount AS t
			WHERE	DistributionServerAdministrationAccount.ServerUID = t.ServerUID
			  AND	DistributionServerAdministrationAccount.AccountID = t.AccountID
		)
	DROP TABLE #DistributionServerAdministrationAccount      -- Drop the temporary table
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[DistributionServerAdministrationAccountRemoveByServerUIDAccountID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[DistributionServerAdministrationAccountRemoveByServerUIDAccountID]
GO
CREATE PROCEDURE [dbo].[DistributionServerAdministrationAccountRemoveByServerUIDAccountID]
	@ServerUID		binary(16),
	@AccountID		int
AS
	DELETE	[dbo].[DistributionServerAdministrationAccount]
	WHERE	ServerUID = @ServerUID
	  AND	AccountID = @AccountID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[DistributionServerAdministrationAccountRemoveAll]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[DistributionServerAdministrationAccountRemoveAll]
GO
CREATE PROCEDURE [dbo].[DistributionServerAdministrationAccountRemoveAll]
	
AS
	DELETE	[dbo].[DistributionServerAdministrationAccount]
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[NetworkDeviceDiscoveredByGetByDeviceIDServerUID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[NetworkDeviceDiscoveredByGetByDeviceIDServerUID]
GO
CREATE PROCEDURE [dbo].[NetworkDeviceDiscoveredByGetByDeviceIDServerUID]
	@DeviceID		int,
	@ServerUID		binary(16)
AS
	SELECT	DeviceID,
		ServerUID,
		CanAdminister,
		LastUpdate,
		AccountID,
		AccountIDOverride
	FROM	[dbo].[NetworkDeviceDiscoveredBy]
	WHERE	DeviceID = @DeviceID
	  AND	ServerUID = @ServerUID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[NetworkDeviceDiscoveredByGetAllByDeviceID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[NetworkDeviceDiscoveredByGetAllByDeviceID]
GO
CREATE PROCEDURE [dbo].[NetworkDeviceDiscoveredByGetAllByDeviceID]
	@DeviceID		int
AS
	SELECT	DeviceID,
		ServerUID,
		CanAdminister,
		LastUpdate,
		AccountID,
		AccountIDOverride
	FROM	[dbo].[NetworkDeviceDiscoveredBy]
	WHERE	DeviceID = @DeviceID
	ORDER BY ServerUID
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[NetworkDeviceDiscoveredByGetAll]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[NetworkDeviceDiscoveredByGetAll]
GO
CREATE PROCEDURE [dbo].[NetworkDeviceDiscoveredByGetAll]
AS
	SELECT	DeviceID,
		ServerUID,
		CanAdminister,
		LastUpdate,
		AccountID,
		AccountIDOverride
	FROM	[dbo].[NetworkDeviceDiscoveredBy]
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[NetworkDeviceDiscoveredByAdd]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[NetworkDeviceDiscoveredByAdd]
GO
CREATE PROCEDURE [dbo].[NetworkDeviceDiscoveredByAdd]
	@DeviceID		int,
	@ServerUID		binary(16),
	@CanAdminister		bit = 0,
	@LastUpdate		datetime,
	@AccountID		int = NULL,
	@AccountIDOverride	int = NULL
AS
	INSERT INTO  dbo.NetworkDeviceDiscoveredBy (
		DeviceID,
		ServerUID,
		CanAdminister,
		LastUpdate,
		AccountID,
		AccountIDOverride
	)
	VALUES (
		@DeviceID,
		@ServerUID,
		@CanAdminister,
		@LastUpdate,
		@AccountID,
		@AccountIDOverride
	)
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[NetworkDeviceDiscoveredBySchema]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[NetworkDeviceDiscoveredBySchema]
GO
CREATE PROCEDURE [dbo].[NetworkDeviceDiscoveredBySchema]
AS
	SELECT
	'IF OBJECT_ID(''tempdb..#NetworkDeviceDiscoveredBy'') IS NULL' + CAST(0x0A AS CHAR(1)) +
	'	CREATE TABLE #NetworkDeviceDiscoveredBy (' + CAST(0x0A AS CHAR(1)) +
	'		DeviceID		int NOT NULL,' + CAST(0x0A AS CHAR(1)) +
	'		ServerUID		binary(16) NOT NULL,' + CAST(0x0A AS CHAR(1)) +
	'		CanAdminister		bit NULL DEFAULT 0,' + CAST(0x0A AS CHAR(1)) +
	'		LastUpdate		datetime NOT NULL DEFAULT getdate(),' + CAST(0x0A AS CHAR(1)) +
	'		AccountID		int NULL,' + CAST(0x0A AS CHAR(1)) +
	'		AccountIDOverride	int NULL' + CAST(0x0A AS CHAR(1)) +
	'	)' + CAST(0x0A AS CHAR(1)) +
	'ELSE' + CAST(0x0A AS CHAR(1)) +
	'	DELETE FROM #NetworkDeviceDiscoveredBy' + CAST(0x0A AS CHAR(1)) +
	'' AS SQL
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[NetworkDeviceDiscoveredByTempAdd]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[NetworkDeviceDiscoveredByTempAdd]
GO
CREATE PROCEDURE dbo.[NetworkDeviceDiscoveredByTempAdd]
	@DeviceID		int,
	@ServerUID		binary(16),
	@CanAdminister		bit = 0,
	@LastUpdate		datetime,
	@AccountID		int = NULL,
	@AccountIDOverride	int = NULL
AS
	INSERT INTO #NetworkDeviceDiscoveredBy (
		DeviceID,
		ServerUID,
		CanAdminister,
		LastUpdate,
		AccountID,
		AccountIDOverride
	)
	VALUES (
		@DeviceID,
		@ServerUID,
		@CanAdminister,
		@LastUpdate,
		@AccountID,
		@AccountIDOverride
	)
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[NetworkDeviceDiscoveredByAddBatch]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[NetworkDeviceDiscoveredByAddBatch]
GO
CREATE PROCEDURE dbo.[NetworkDeviceDiscoveredByAddBatch]
AS
	DECLARE @count int
	INSERT dbo.NetworkDeviceDiscoveredBy (
		DeviceID,
		ServerUID,
		CanAdminister,
		LastUpdate,
		AccountID,
		AccountIDOverride
	)
		SELECT	DeviceID,
			ServerUID,
			CanAdminister,
			LastUpdate,
			AccountID,
			AccountIDOverride
		FROM #NetworkDeviceDiscoveredBy
	SET @count = @@ROWCOUNT
	DROP TABLE #NetworkDeviceDiscoveredBy	-- Drop temporary table
	RETURN @count
GO

/*
Add new NetworkDeviceDiscoveredBy bound to
	AdministrationAccount using AccountName
	AdministrationAccount using AccountName
	with DeviceID, ServerUID, CanAdminister, LastUpdate
*/

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[NetworkDeviceDiscoveredByUpdateByDeviceIDServerUID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[NetworkDeviceDiscoveredByUpdateByDeviceIDServerUID]
GO
CREATE PROCEDURE [dbo].[NetworkDeviceDiscoveredByUpdateByDeviceIDServerUID]
	@DeviceID		int,
	@ServerUID		binary(16),
	@CanAdminister		bit = 0,
	@LastUpdate		datetime,
	@AccountID		int = NULL,
	@AccountIDOverride	int = NULL
AS
	UPDATE	[dbo].[NetworkDeviceDiscoveredBy]
	SET	CanAdminister = @CanAdminister,
		LastUpdate = @LastUpdate,
		AccountID = @AccountID,
		AccountIDOverride = @AccountIDOverride
	WHERE	DeviceID = @DeviceID
	  AND	ServerUID = @ServerUID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[NetworkDeviceDiscoveredByUpdateBatchByDeviceIDServerUID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[NetworkDeviceDiscoveredByUpdateBatchByDeviceIDServerUID]
GO
CREATE PROCEDURE dbo.[NetworkDeviceDiscoveredByUpdateBatchByDeviceIDServerUID]
AS
	DECLARE @count int

	CREATE INDEX [TempNetworkDeviceDiscoveredByDeviceIDServerUID]
		ON #NetworkDeviceDiscoveredBy (DeviceID, ServerUID)

	UPDATE	[dbo].[NetworkDeviceDiscoveredBy]
	SET	CanAdminister = t.CanAdminister,
		LastUpdate = t.LastUpdate,
		AccountID = t.AccountID,
		AccountIDOverride = t.AccountIDOverride
	FROM	#NetworkDeviceDiscoveredBy AS t
	WHERE	NetworkDeviceDiscoveredBy.DeviceID = t.DeviceID
	  AND	NetworkDeviceDiscoveredBy.ServerUID = t.ServerUID
	SET @count = @@ROWCOUNT
	DROP TABLE #NetworkDeviceDiscoveredBy	-- Drop the temporary table
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[NetworkDeviceDiscoveredByPutByDeviceIDServerUID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[NetworkDeviceDiscoveredByPutByDeviceIDServerUID]
GO
CREATE PROCEDURE [dbo].[NetworkDeviceDiscoveredByPutByDeviceIDServerUID]
	@DeviceID		int,
	@ServerUID		binary(16),
	@CanAdminister		bit = 0,
	@LastUpdate		datetime,
	@AccountID		int = NULL,
	@AccountIDOverride	int = NULL
AS
	IF NOT EXISTS(
		SELECT	1
		FROM	dbo.NetworkDeviceDiscoveredBy
		WHERE	DeviceID = @DeviceID
		  AND	ServerUID = @ServerUID
	)
		EXEC NetworkDeviceDiscoveredByAdd @DeviceID,
			@ServerUID,
			@CanAdminister,
			@LastUpdate,
			@AccountID,
			@AccountIDOverride
	ELSE
		EXEC NetworkDeviceDiscoveredByUpdateByDeviceIDServerUID @DeviceID,
			@ServerUID,
			@CanAdminister,
			@LastUpdate,
			@AccountID,
			@AccountIDOverride
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[NetworkDeviceDiscoveredByPutBatchByDeviceIDServerUID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[NetworkDeviceDiscoveredByPutBatchByDeviceIDServerUID]
GO
CREATE PROCEDURE [dbo].[NetworkDeviceDiscoveredByPutBatchByDeviceIDServerUID]
AS
	DECLARE @count AS int
	SET @count = 0

	CREATE INDEX [TempNetworkDeviceDiscoveredByDeviceIDServerUID]
		ON #NetworkDeviceDiscoveredBy (DeviceID, ServerUID)

	BEGIN TRANSACTION
	UPDATE [dbo].[NetworkDeviceDiscoveredBy]
		SET	CanAdminister = t.CanAdminister,
			LastUpdate = t.LastUpdate,
			AccountID = t.AccountID,
			AccountIDOverride = t.AccountIDOverride
		FROM	#NetworkDeviceDiscoveredBy AS t
		WHERE	NetworkDeviceDiscoveredBy.DeviceID = t.DeviceID
		  AND	NetworkDeviceDiscoveredBy.ServerUID = t.ServerUID
	SET @count = @@ROWCOUNT

	INSERT [dbo].[NetworkDeviceDiscoveredBy] (
		DeviceID,
		ServerUID,
		CanAdminister,
		LastUpdate,
		AccountID,
		AccountIDOverride
	)
		SELECT	DeviceID,
			ServerUID,
			CanAdminister,
			LastUpdate,
			AccountID,
			AccountIDOverride
		FROM	#NetworkDeviceDiscoveredBy AS t
		WHERE NOT EXISTS(	-- Current record doesn't exist
			SELECT * FROM [dbo].[NetworkDeviceDiscoveredBy]
			WHERE	NetworkDeviceDiscoveredBy.DeviceID = t.DeviceID
			  AND	NetworkDeviceDiscoveredBy.ServerUID = t.ServerUID
		)
	SET @count = @count + @@ROWCOUNT
	DROP TABLE #NetworkDeviceDiscoveredBy	-- Drop the temporary table
	COMMIT WORK
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[NetworkDeviceDiscoveredByRemoveBatch]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[NetworkDeviceDiscoveredByRemoveBatch]
GO

CREATE PROCEDURE [dbo].[NetworkDeviceDiscoveredByRemoveBatch]
AS

	CREATE INDEX [TempNetworkDeviceDiscoveredByNetworkDeviceDiscoveredByRemoveBatch]
		ON #NetworkDeviceDiscoveredBy (DeviceID, ServerUID)	

	-- Delete records from NetworkDeviceDiscoveredBy identified by fields of [TempNetworkDeviceDiscoveredByNetworkDeviceDiscoveredByRemoveBatch]
	DELETE [dbo].[NetworkDeviceDiscoveredBy]
	WHERE EXISTS(
			SELECT * FROM #NetworkDeviceDiscoveredBy AS t
			WHERE	NetworkDeviceDiscoveredBy.DeviceID = t.DeviceID
			  AND	NetworkDeviceDiscoveredBy.ServerUID = t.ServerUID
		)
	DROP TABLE #NetworkDeviceDiscoveredBy      -- Drop the temporary table
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[NetworkDeviceDiscoveredByRemoveByDeviceIDServerUID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[NetworkDeviceDiscoveredByRemoveByDeviceIDServerUID]
GO
CREATE PROCEDURE [dbo].[NetworkDeviceDiscoveredByRemoveByDeviceIDServerUID]
	@DeviceID		int,
	@ServerUID		binary(16)
AS
	DELETE	[dbo].[NetworkDeviceDiscoveredBy]
	WHERE	DeviceID = @DeviceID
	  AND	ServerUID = @ServerUID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[NetworkDeviceDiscoveredByRemoveAll]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[NetworkDeviceDiscoveredByRemoveAll]
GO
CREATE PROCEDURE [dbo].[NetworkDeviceDiscoveredByRemoveAll]
	
AS
	DELETE	[dbo].[NetworkDeviceDiscoveredBy]
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[KnownOracleListenerGetByID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[KnownOracleListenerGetByID]
GO
CREATE PROCEDURE [dbo].[KnownOracleListenerGetByID]
	@KnownOracleListenerID	int
AS
	SELECT	KnownOracleListenerID,
		DeviceID,
		Port,
		[Name],
		Version,
		ManuallyAdded
	FROM	[dbo].[KnownOracleListener]
	WHERE	KnownOracleListenerID = @KnownOracleListenerID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[KnownOracleListenerGetByDeviceIDPort]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[KnownOracleListenerGetByDeviceIDPort]
GO
CREATE PROCEDURE [dbo].[KnownOracleListenerGetByDeviceIDPort]
	@DeviceID		int,
	@Port			int = 1521
AS
	SELECT	KnownOracleListenerID,
		DeviceID,
		Port,
		[Name],
		Version,
		ManuallyAdded
	FROM	[dbo].[KnownOracleListener]
	WHERE	DeviceID = @DeviceID
	  AND	Port = @Port
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[KnownOracleListenerGetAllByDeviceID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[KnownOracleListenerGetAllByDeviceID]
GO
CREATE PROCEDURE [dbo].[KnownOracleListenerGetAllByDeviceID]
	@DeviceID		int
AS
	SELECT	KnownOracleListenerID,
		DeviceID,
		Port,
		[Name],
		Version,
		ManuallyAdded
	FROM	[dbo].[KnownOracleListener]
	WHERE	DeviceID = @DeviceID
	ORDER BY Port
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[KnownOracleListenerGetAll]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[KnownOracleListenerGetAll]
GO
CREATE PROCEDURE [dbo].[KnownOracleListenerGetAll]
AS
	SELECT	KnownOracleListenerID,
		DeviceID,
		Port,
		[Name],
		Version,
		ManuallyAdded
	FROM	[dbo].[KnownOracleListener]
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[KnownOracleListenerAdd]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[KnownOracleListenerAdd]
GO
CREATE PROCEDURE [dbo].[KnownOracleListenerAdd]
	@DeviceID		int,
	@Port			int = 1521,
	@Name			nvarchar(128),
	@Version		nvarchar(32),
	@ManuallyAdded		bit = 1
AS
	INSERT INTO  dbo.KnownOracleListener (
		DeviceID,
		Port,
		[Name],
		Version,
		ManuallyAdded
	)
	VALUES (
		@DeviceID,
		@Port,
		@Name,
		@Version,
		@ManuallyAdded
	)
	RETURN SCOPE_IDENTITY()
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[KnownOracleListenerBind]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[KnownOracleListenerBind]
GO
CREATE PROCEDURE [dbo].[KnownOracleListenerBind]
	@DeviceID		int,
	@Port			int = 1521,
	@Name			nvarchar(128),
	@Version		nvarchar(32),
	@ManuallyAdded		bit = 1
AS
	DECLARE	@ID	int

	SELECT	@ID = KnownOracleListenerID
	FROM	[dbo].[KnownOracleListener]
	WHERE	DeviceID = @DeviceID
	  AND	Port = @Port

	IF @ID IS NULL
		EXEC @ID = KnownOracleListenerAdd @DeviceID,
			@Port,
			@Name,
			@Version,
			@ManuallyAdded

	RETURN @ID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[KnownOracleListenerSchema]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[KnownOracleListenerSchema]
GO
CREATE PROCEDURE [dbo].[KnownOracleListenerSchema]
AS
	SELECT
	'IF OBJECT_ID(''tempdb..#KnownOracleListener'') IS NULL' + CAST(0x0A AS CHAR(1)) +
	'	CREATE TABLE #KnownOracleListener (' + CAST(0x0A AS CHAR(1)) +
	'		KnownOracleListenerID	int NULL,' + CAST(0x0A AS CHAR(1)) +
	'		DeviceID		int NOT NULL,' + CAST(0x0A AS CHAR(1)) +
	'		Port			int NOT NULL DEFAULT 1521,' + CAST(0x0A AS CHAR(1)) +
	'		[Name]			nvarchar(128) COLLATE database_default NOT NULL,' + CAST(0x0A AS CHAR(1)) +
	'		Version			nvarchar(32) COLLATE database_default NOT NULL,' + CAST(0x0A AS CHAR(1)) +
	'		ManuallyAdded		bit NOT NULL DEFAULT 1' + CAST(0x0A AS CHAR(1)) +
	'	)' + CAST(0x0A AS CHAR(1)) +
	'ELSE' + CAST(0x0A AS CHAR(1)) +
	'	DELETE FROM #KnownOracleListener' + CAST(0x0A AS CHAR(1)) +
	'' AS SQL
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[KnownOracleListenerTempAdd]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[KnownOracleListenerTempAdd]
GO
CREATE PROCEDURE dbo.[KnownOracleListenerTempAdd]
	@KnownOracleListenerID	int,
	@DeviceID		int,
	@Port			int = 1521,
	@Name			nvarchar(128),
	@Version		nvarchar(32),
	@ManuallyAdded		bit = 1
AS
	INSERT INTO #KnownOracleListener (
		KnownOracleListenerID,
		DeviceID,
		Port,
		[Name],
		Version,
		ManuallyAdded
	)
	VALUES (
		@KnownOracleListenerID,
		@DeviceID,
		@Port,
		@Name,
		@Version,
		@ManuallyAdded
	)
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[KnownOracleListenerAddBatch]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[KnownOracleListenerAddBatch]
GO
CREATE PROCEDURE dbo.[KnownOracleListenerAddBatch]
AS
	DECLARE @count int
	INSERT dbo.KnownOracleListener (
		DeviceID,
		Port,
		[Name],
		Version,
		ManuallyAdded
	)
		SELECT	DeviceID,
			Port,
			[Name],
			Version,
			ManuallyAdded
		FROM #KnownOracleListener
	SET @count = @@ROWCOUNT
	DROP TABLE #KnownOracleListener	-- Drop temporary table
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[KnownOracleListenerUpdateByID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[KnownOracleListenerUpdateByID]
GO
CREATE PROCEDURE [dbo].[KnownOracleListenerUpdateByID]
	@KnownOracleListenerID	int,
	@DeviceID		int,
	@Port			int = 1521,
	@Name			nvarchar(128),
	@Version		nvarchar(32),
	@ManuallyAdded		bit = 1
AS
	DECLARE	@ID	int
	SET @ID = 0

	UPDATE	[dbo].[KnownOracleListener]
	SET	@ID = KnownOracleListenerID,
		DeviceID = @DeviceID,
		Port = @Port,
		[Name] = @Name,
		Version = @Version,
		ManuallyAdded = @ManuallyAdded
	WHERE	KnownOracleListenerID = @KnownOracleListenerID
	RETURN @ID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[KnownOracleListenerUpdateBatchByID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[KnownOracleListenerUpdateBatchByID]
GO
CREATE PROCEDURE dbo.[KnownOracleListenerUpdateBatchByID]
AS
	DECLARE @count int

	CREATE INDEX [TempKnownOracleListenerID]
		ON #KnownOracleListener (KnownOracleListenerID)

	UPDATE	[dbo].[KnownOracleListener]
	SET	DeviceID = t.DeviceID,
		Port = t.Port,
		[Name] = t.[Name],
		Version = t.Version,
		ManuallyAdded = t.ManuallyAdded
	FROM	#KnownOracleListener AS t
	WHERE	KnownOracleListener.KnownOracleListenerID = t.KnownOracleListenerID
	SET @count = @@ROWCOUNT
	DROP TABLE #KnownOracleListener	-- Drop the temporary table
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[KnownOracleListenerUpdateByDeviceIDPort]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[KnownOracleListenerUpdateByDeviceIDPort]
GO
CREATE PROCEDURE [dbo].[KnownOracleListenerUpdateByDeviceIDPort]
	@DeviceID		int,
	@Port			int = 1521,
	@Name			nvarchar(128),
	@Version		nvarchar(32),
	@ManuallyAdded		bit = 1
AS
	DECLARE	@ID	int
	SET @ID = 0

	UPDATE	[dbo].[KnownOracleListener]
	SET	@ID = KnownOracleListenerID,
		[Name] = @Name,
		Version = @Version,
		ManuallyAdded = @ManuallyAdded
	WHERE	DeviceID = @DeviceID
	  AND	Port = @Port
	RETURN @ID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[KnownOracleListenerUpdateBatchByDeviceIDPort]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[KnownOracleListenerUpdateBatchByDeviceIDPort]
GO
CREATE PROCEDURE dbo.[KnownOracleListenerUpdateBatchByDeviceIDPort]
AS
	DECLARE @count int

	CREATE INDEX [TempKnownOracleListenerDeviceIDPort]
		ON #KnownOracleListener (DeviceID, Port)

	UPDATE	[dbo].[KnownOracleListener]
	SET	[Name] = t.[Name],
		Version = t.Version,
		ManuallyAdded = t.ManuallyAdded
	FROM	#KnownOracleListener AS t
	WHERE	KnownOracleListener.DeviceID = t.DeviceID
	  AND	KnownOracleListener.Port = t.Port
	SET @count = @@ROWCOUNT
	DROP TABLE #KnownOracleListener	-- Drop the temporary table
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[KnownOracleListenerPutByDeviceIDPort]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[KnownOracleListenerPutByDeviceIDPort]
GO
CREATE PROCEDURE [dbo].[KnownOracleListenerPutByDeviceIDPort]
	@DeviceID		int,
	@Port			int = 1521,
	@Name			nvarchar(128),
	@Version		nvarchar(32),
	@ManuallyAdded		bit = 1
AS
	DECLARE @ID	int

	SELECT	@ID = KnownOracleListenerID
	FROM	KnownOracleListener
	WHERE	DeviceID = @DeviceID
	  AND	Port = @Port

	IF @ID IS NULL
		EXEC @ID = KnownOracleListenerAdd @DeviceID,
			@Port,
			@Name,
			@Version,
			@ManuallyAdded
	ELSE
		EXEC KnownOracleListenerUpdateByDeviceIDPort @DeviceID,
			@Port,
			@Name,
			@Version,
			@ManuallyAdded

	RETURN @ID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[KnownOracleListenerPutBatchByDeviceIDPort]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[KnownOracleListenerPutBatchByDeviceIDPort]
GO
CREATE PROCEDURE [dbo].[KnownOracleListenerPutBatchByDeviceIDPort]
AS
	DECLARE @count AS int
	SET @count = 0

	CREATE INDEX [TempKnownOracleListenerDeviceIDPort]
		ON #KnownOracleListener (DeviceID, Port)

	BEGIN TRANSACTION
	UPDATE [dbo].[KnownOracleListener]
		SET	[Name] = t.[Name],
			Version = t.Version,
			ManuallyAdded = t.ManuallyAdded
		FROM	#KnownOracleListener AS t
		WHERE	KnownOracleListener.DeviceID = t.DeviceID
		  AND	KnownOracleListener.Port = t.Port
	SET @count = @@ROWCOUNT

	INSERT [dbo].[KnownOracleListener] (
		DeviceID,
		Port,
		[Name],
		Version,
		ManuallyAdded
	)
		SELECT	DeviceID,
			Port,
			[Name],
			Version,
			ManuallyAdded
		FROM	#KnownOracleListener AS t
		WHERE NOT EXISTS(	-- Current record doesn't exist
			SELECT * FROM [dbo].[KnownOracleListener]
			WHERE	KnownOracleListener.DeviceID = t.DeviceID
			  AND	KnownOracleListener.Port = t.Port
		)
	SET @count = @count + @@ROWCOUNT
	DROP TABLE #KnownOracleListener	-- Drop the temporary table
	COMMIT WORK
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[KnownOracleListenerRemoveBatch]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[KnownOracleListenerRemoveBatch]
GO

CREATE PROCEDURE [dbo].[KnownOracleListenerRemoveBatch]
AS

	CREATE INDEX [TempKnownOracleListenerKnownOracleListenerRemoveBatch]
		ON #KnownOracleListener (KnownOracleListenerID)	

	-- Delete records from KnownOracleListener identified by fields of [TempKnownOracleListenerKnownOracleListenerRemoveBatch]
	DELETE [dbo].[KnownOracleListener]
	WHERE EXISTS(
			SELECT * FROM #KnownOracleListener AS t
			WHERE	KnownOracleListener.KnownOracleListenerID = t.KnownOracleListenerID
		)
	DROP TABLE #KnownOracleListener      -- Drop the temporary table
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[KnownOracleListenerRemoveByID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[KnownOracleListenerRemoveByID]
GO
CREATE PROCEDURE [dbo].[KnownOracleListenerRemoveByID]
	@KnownOracleListenerID	int
AS
	-- KnownOracleListener deletes cascade to:
	--	KnownOracleService by FK_KnownOracleService_KnownOracleListener
	DELETE	[dbo].[KnownOracleListener]
	WHERE	KnownOracleListenerID = @KnownOracleListenerID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[KnownOracleListenerRemoveByDeviceIDPort]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[KnownOracleListenerRemoveByDeviceIDPort]
GO
CREATE PROCEDURE [dbo].[KnownOracleListenerRemoveByDeviceIDPort]
	@DeviceID		int,
	@Port			int = 1521
AS
	-- KnownOracleListener deletes cascade to:
	--	KnownOracleService by FK_KnownOracleService_KnownOracleListener
	DELETE	[dbo].[KnownOracleListener]
	WHERE	DeviceID = @DeviceID
	  AND	Port = @Port
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[KnownOracleListenerRemoveAllByDeviceID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[KnownOracleListenerRemoveAllByDeviceID]
GO
CREATE PROCEDURE [dbo].[KnownOracleListenerRemoveAllByDeviceID]
	@DeviceID		int
AS
	DELETE	[dbo].[KnownOracleListener]
	WHERE	DeviceID = @DeviceID
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[KnownOracleListenerRemoveAll]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[KnownOracleListenerRemoveAll]
GO
CREATE PROCEDURE [dbo].[KnownOracleListenerRemoveAll]
	
AS
	DELETE	[dbo].[KnownOracleListener]
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[KnownOracleServiceGetByID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[KnownOracleServiceGetByID]
GO
CREATE PROCEDURE [dbo].[KnownOracleServiceGetByID]
	@KnownOracleServiceID	int
AS
	SELECT	KnownOracleServiceID,
		KnownOracleListenerID,
		DeviceID,
		[Name],
		ManuallyAdded
	FROM	[dbo].[KnownOracleService]
	WHERE	KnownOracleServiceID = @KnownOracleServiceID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[KnownOracleServiceGetByKnownOracleListenerIDName]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[KnownOracleServiceGetByKnownOracleListenerIDName]
GO
CREATE PROCEDURE [dbo].[KnownOracleServiceGetByKnownOracleListenerIDName]
	@KnownOracleListenerID	int = NULL,
	@Name			nvarchar(128)
AS
	SELECT	KnownOracleServiceID,
		KnownOracleListenerID,
		DeviceID,
		[Name],
		ManuallyAdded
	FROM	[dbo].[KnownOracleService]
	WHERE	(KnownOracleListenerID = @KnownOracleListenerID OR (KnownOracleListenerID IS NULL AND @KnownOracleListenerID IS NULL))
	  AND	[Name] = @Name
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[KnownOracleServiceGetAllByKnownOracleListenerID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[KnownOracleServiceGetAllByKnownOracleListenerID]
GO
CREATE PROCEDURE [dbo].[KnownOracleServiceGetAllByKnownOracleListenerID]
	@KnownOracleListenerID	int = NULL
AS
	SELECT	KnownOracleServiceID,
		KnownOracleListenerID,
		DeviceID,
		[Name],
		ManuallyAdded
	FROM	[dbo].[KnownOracleService]
	WHERE	(KnownOracleListenerID = @KnownOracleListenerID OR (KnownOracleListenerID IS NULL AND @KnownOracleListenerID IS NULL))
	ORDER BY [Name]
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[KnownOracleServiceGetAllByDeviceID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[KnownOracleServiceGetAllByDeviceID]
GO
CREATE PROCEDURE [dbo].[KnownOracleServiceGetAllByDeviceID]
	@DeviceID		int
AS
	SELECT	KnownOracleServiceID,
		KnownOracleListenerID,
		DeviceID,
		[Name],
		ManuallyAdded
	FROM	[dbo].[KnownOracleService]
	WHERE	DeviceID = @DeviceID
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[KnownOracleServiceGetAll]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[KnownOracleServiceGetAll]
GO
CREATE PROCEDURE [dbo].[KnownOracleServiceGetAll]
AS
	SELECT	KnownOracleServiceID,
		KnownOracleListenerID,
		DeviceID,
		[Name],
		ManuallyAdded
	FROM	[dbo].[KnownOracleService]
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[KnownOracleServiceAdd]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[KnownOracleServiceAdd]
GO
CREATE PROCEDURE [dbo].[KnownOracleServiceAdd]
	@KnownOracleListenerID	int = NULL,
	@DeviceID		int,
	@Name			nvarchar(128),
	@ManuallyAdded		bit = 1
AS
	INSERT INTO  dbo.KnownOracleService (
		KnownOracleListenerID,
		DeviceID,
		[Name],
		ManuallyAdded
	)
	VALUES (
		@KnownOracleListenerID,
		@DeviceID,
		@Name,
		@ManuallyAdded
	)
	RETURN SCOPE_IDENTITY()
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[KnownOracleServiceBind]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[KnownOracleServiceBind]
GO
CREATE PROCEDURE [dbo].[KnownOracleServiceBind]
	@KnownOracleListenerID	int = NULL,
	@DeviceID		int,
	@Name			nvarchar(128),
	@ManuallyAdded		bit = 1
AS
	DECLARE	@ID	int

	SELECT	@ID = KnownOracleServiceID
	FROM	[dbo].[KnownOracleService]
	WHERE	(KnownOracleListenerID = @KnownOracleListenerID OR (KnownOracleListenerID IS NULL AND @KnownOracleListenerID IS NULL))
	  AND	[Name] = @Name

	IF @ID IS NULL
		EXEC @ID = KnownOracleServiceAdd @KnownOracleListenerID,
			@DeviceID,
			@Name,
			@ManuallyAdded

	RETURN @ID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[KnownOracleServiceSchema]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[KnownOracleServiceSchema]
GO
CREATE PROCEDURE [dbo].[KnownOracleServiceSchema]
AS
	SELECT
	'IF OBJECT_ID(''tempdb..#KnownOracleService'') IS NULL' + CAST(0x0A AS CHAR(1)) +
	'	CREATE TABLE #KnownOracleService (' + CAST(0x0A AS CHAR(1)) +
	'		KnownOracleServiceID	int NULL,' + CAST(0x0A AS CHAR(1)) +
	'		KnownOracleListenerID	int NULL,' + CAST(0x0A AS CHAR(1)) +
	'		DeviceID		int NOT NULL,' + CAST(0x0A AS CHAR(1)) +
	'		[Name]			nvarchar(128) COLLATE database_default NOT NULL,' + CAST(0x0A AS CHAR(1)) +
	'		ManuallyAdded		bit NOT NULL DEFAULT 1' + CAST(0x0A AS CHAR(1)) +
	'	)' + CAST(0x0A AS CHAR(1)) +
	'ELSE' + CAST(0x0A AS CHAR(1)) +
	'	DELETE FROM #KnownOracleService' + CAST(0x0A AS CHAR(1)) +
	'' AS SQL
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[KnownOracleServiceTempAdd]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[KnownOracleServiceTempAdd]
GO
CREATE PROCEDURE dbo.[KnownOracleServiceTempAdd]
	@KnownOracleServiceID	int,
	@KnownOracleListenerID	int = NULL,
	@DeviceID		int,
	@Name			nvarchar(128),
	@ManuallyAdded		bit = 1
AS
	INSERT INTO #KnownOracleService (
		KnownOracleServiceID,
		KnownOracleListenerID,
		DeviceID,
		[Name],
		ManuallyAdded
	)
	VALUES (
		@KnownOracleServiceID,
		@KnownOracleListenerID,
		@DeviceID,
		@Name,
		@ManuallyAdded
	)
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[KnownOracleServiceAddBatch]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[KnownOracleServiceAddBatch]
GO
CREATE PROCEDURE dbo.[KnownOracleServiceAddBatch]
AS
	DECLARE @count int
	INSERT dbo.KnownOracleService (
		KnownOracleListenerID,
		DeviceID,
		[Name],
		ManuallyAdded
	)
		SELECT	KnownOracleListenerID,
			DeviceID,
			[Name],
			ManuallyAdded
		FROM #KnownOracleService
	SET @count = @@ROWCOUNT
	DROP TABLE #KnownOracleService	-- Drop temporary table
	RETURN @count
GO

/*
Add new KnownOracleService bound to
	KnownOracleListener using DeviceID, Port with Name, Version
	with DeviceID, Name, ManuallyAdded
*/

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[KnownOracleServiceUpdateByID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[KnownOracleServiceUpdateByID]
GO
CREATE PROCEDURE [dbo].[KnownOracleServiceUpdateByID]
	@KnownOracleServiceID	int,
	@KnownOracleListenerID	int = NULL,
	@DeviceID		int,
	@Name			nvarchar(128),
	@ManuallyAdded		bit = 1
AS
	DECLARE	@ID	int
	SET @ID = 0

	UPDATE	[dbo].[KnownOracleService]
	SET	@ID = KnownOracleServiceID,
		KnownOracleListenerID = @KnownOracleListenerID,
		DeviceID = @DeviceID,
		[Name] = @Name,
		ManuallyAdded = @ManuallyAdded
	WHERE	KnownOracleServiceID = @KnownOracleServiceID
	RETURN @ID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[KnownOracleServiceUpdateBatchByID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[KnownOracleServiceUpdateBatchByID]
GO
CREATE PROCEDURE dbo.[KnownOracleServiceUpdateBatchByID]
AS
	DECLARE @count int

	CREATE INDEX [TempKnownOracleServiceID]
		ON #KnownOracleService (KnownOracleServiceID)

	UPDATE	[dbo].[KnownOracleService]
	SET	KnownOracleListenerID = t.KnownOracleListenerID,
		DeviceID = t.DeviceID,
		[Name] = t.[Name],
		ManuallyAdded = t.ManuallyAdded
	FROM	#KnownOracleService AS t
	WHERE	KnownOracleService.KnownOracleServiceID = t.KnownOracleServiceID
	SET @count = @@ROWCOUNT
	DROP TABLE #KnownOracleService	-- Drop the temporary table
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[KnownOracleServiceUpdateByKnownOracleListenerIDName]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[KnownOracleServiceUpdateByKnownOracleListenerIDName]
GO
CREATE PROCEDURE [dbo].[KnownOracleServiceUpdateByKnownOracleListenerIDName]
	@KnownOracleListenerID	int = NULL,
	@Name			nvarchar(128),
	@DeviceID		int,
	@ManuallyAdded		bit = 1
AS
	DECLARE	@ID	int
	SET @ID = 0

	UPDATE	[dbo].[KnownOracleService]
	SET	@ID = KnownOracleServiceID,
		DeviceID = @DeviceID,
		ManuallyAdded = @ManuallyAdded
	WHERE	(KnownOracleListenerID = @KnownOracleListenerID OR (KnownOracleListenerID IS NULL AND @KnownOracleListenerID IS NULL))
	  AND	[Name] = @Name
	RETURN @ID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[KnownOracleServiceUpdateBatchByKnownOracleListenerIDName]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[KnownOracleServiceUpdateBatchByKnownOracleListenerIDName]
GO
CREATE PROCEDURE dbo.[KnownOracleServiceUpdateBatchByKnownOracleListenerIDName]
AS
	DECLARE @count int

	CREATE INDEX [TempKnownOracleServiceKnownOracleListenerIDName]
		ON #KnownOracleService (KnownOracleListenerID, [Name])

	UPDATE	[dbo].[KnownOracleService]
	SET	DeviceID = t.DeviceID,
		ManuallyAdded = t.ManuallyAdded
	FROM	#KnownOracleService AS t
	WHERE	(KnownOracleService.KnownOracleListenerID = t.KnownOracleListenerID OR (KnownOracleService.KnownOracleListenerID IS NULL AND t.KnownOracleListenerID IS NULL))
	  AND	KnownOracleService.[Name] = t.[Name]
	SET @count = @@ROWCOUNT
	DROP TABLE #KnownOracleService	-- Drop the temporary table
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[KnownOracleServicePutByKnownOracleListenerIDName]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[KnownOracleServicePutByKnownOracleListenerIDName]
GO
CREATE PROCEDURE [dbo].[KnownOracleServicePutByKnownOracleListenerIDName]
	@KnownOracleListenerID	int = NULL,
	@Name			nvarchar(128),
	@DeviceID		int,
	@ManuallyAdded		bit = 1
AS
	DECLARE @ID	int

	SELECT	@ID = KnownOracleServiceID
	FROM	KnownOracleService
	WHERE	(KnownOracleListenerID = @KnownOracleListenerID OR (KnownOracleListenerID IS NULL AND @KnownOracleListenerID IS NULL))
	  AND	[Name] = @Name

	IF @ID IS NULL
		EXEC @ID = KnownOracleServiceAdd @KnownOracleListenerID,
			@DeviceID,
			@Name,
			@ManuallyAdded
	ELSE
		EXEC KnownOracleServiceUpdateByKnownOracleListenerIDName @KnownOracleListenerID,
			@Name,
			@DeviceID,
			@ManuallyAdded

	RETURN @ID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[KnownOracleServicePutBatchByKnownOracleListenerIDName]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[KnownOracleServicePutBatchByKnownOracleListenerIDName]
GO
CREATE PROCEDURE [dbo].[KnownOracleServicePutBatchByKnownOracleListenerIDName]
AS
	DECLARE @count AS int
	SET @count = 0

	CREATE INDEX [TempKnownOracleServiceKnownOracleListenerIDName]
		ON #KnownOracleService (KnownOracleListenerID, [Name])

	BEGIN TRANSACTION
	UPDATE [dbo].[KnownOracleService]
		SET	DeviceID = t.DeviceID,
			ManuallyAdded = t.ManuallyAdded
		FROM	#KnownOracleService AS t
		WHERE	(KnownOracleService.KnownOracleListenerID = t.KnownOracleListenerID OR (KnownOracleService.KnownOracleListenerID IS NULL AND t.KnownOracleListenerID IS NULL))
		  AND	KnownOracleService.[Name] = t.[Name]
	SET @count = @@ROWCOUNT

	INSERT [dbo].[KnownOracleService] (
		KnownOracleListenerID,
		DeviceID,
		[Name],
		ManuallyAdded
	)
		SELECT	KnownOracleListenerID,
			DeviceID,
			[Name],
			ManuallyAdded
		FROM	#KnownOracleService AS t
		WHERE NOT EXISTS(	-- Current record doesn't exist
			SELECT * FROM [dbo].[KnownOracleService]
			WHERE	(KnownOracleService.KnownOracleListenerID = t.KnownOracleListenerID OR (KnownOracleService.KnownOracleListenerID IS NULL AND t.KnownOracleListenerID IS NULL))
			  AND	KnownOracleService.[Name] = t.[Name]
		)
	SET @count = @count + @@ROWCOUNT
	DROP TABLE #KnownOracleService	-- Drop the temporary table
	COMMIT WORK
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[KnownOracleServiceRemoveBatch]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[KnownOracleServiceRemoveBatch]
GO

CREATE PROCEDURE [dbo].[KnownOracleServiceRemoveBatch]
AS

	CREATE INDEX [TempKnownOracleServiceKnownOracleServiceRemoveBatch]
		ON #KnownOracleService (KnownOracleServiceID)	

	-- Delete records from KnownOracleService identified by fields of [TempKnownOracleServiceKnownOracleServiceRemoveBatch]
	DELETE [dbo].[KnownOracleService]
	WHERE EXISTS(
			SELECT * FROM #KnownOracleService AS t
			WHERE	KnownOracleService.KnownOracleServiceID = t.KnownOracleServiceID
		)
	DROP TABLE #KnownOracleService      -- Drop the temporary table
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[KnownOracleServiceRemoveByID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[KnownOracleServiceRemoveByID]
GO
CREATE PROCEDURE [dbo].[KnownOracleServiceRemoveByID]
	@KnownOracleServiceID	int
AS
	DELETE	[dbo].[KnownOracleService]
	WHERE	KnownOracleServiceID = @KnownOracleServiceID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[KnownOracleServiceRemoveByKnownOracleListenerIDName]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[KnownOracleServiceRemoveByKnownOracleListenerIDName]
GO
CREATE PROCEDURE [dbo].[KnownOracleServiceRemoveByKnownOracleListenerIDName]
	@KnownOracleListenerID	int = NULL,
	@Name			nvarchar(128)
AS
	DELETE	[dbo].[KnownOracleService]
	WHERE	(KnownOracleListenerID = @KnownOracleListenerID OR (KnownOracleListenerID IS NULL AND @KnownOracleListenerID IS NULL))
	  AND	[Name] = @Name
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[KnownOracleServiceRemoveAllByKnownOracleListenerID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[KnownOracleServiceRemoveAllByKnownOracleListenerID]
GO
CREATE PROCEDURE [dbo].[KnownOracleServiceRemoveAllByKnownOracleListenerID]
	@KnownOracleListenerID	int = NULL
AS
	DELETE	[dbo].[KnownOracleService]
	WHERE	(KnownOracleListenerID = @KnownOracleListenerID OR (KnownOracleListenerID IS NULL AND @KnownOracleListenerID IS NULL))
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[KnownOracleServiceRemoveAll]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[KnownOracleServiceRemoveAll]
GO
CREATE PROCEDURE [dbo].[KnownOracleServiceRemoveAll]
	
AS
	DELETE	[dbo].[KnownOracleService]
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[TaskTypeGetByID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[TaskTypeGetByID]
GO
CREATE PROCEDURE [dbo].[TaskTypeGetByID]
	@TaskTypeID		int
AS
	SELECT	TaskTypeID,
		TaskTypeName
	FROM	[dbo].[TaskType]
	WHERE	TaskTypeID = @TaskTypeID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[TaskTypeGetByName]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[TaskTypeGetByName]
GO
CREATE PROCEDURE [dbo].[TaskTypeGetByName]
	@TaskTypeName		nvarchar(32)
AS
	SELECT	TaskTypeID,
		TaskTypeName
	FROM	[dbo].[TaskType]
	WHERE	TaskTypeName = @TaskTypeName
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[TaskTypeGetAll]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[TaskTypeGetAll]
GO
CREATE PROCEDURE [dbo].[TaskTypeGetAll]
AS
	SELECT	TaskTypeID,
		TaskTypeName
	FROM	[dbo].[TaskType]
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[TaskTypeBind]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[TaskTypeBind]
GO
CREATE PROCEDURE [dbo].[TaskTypeBind]
	@TaskTypeName		nvarchar(32)
AS
	DECLARE	@ID	int

	SELECT	@ID = TaskTypeID
	FROM	[dbo].[TaskType]
	WHERE	TaskTypeName = @TaskTypeName

	RETURN @ID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[TaskScheduleGetByID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[TaskScheduleGetByID]
GO
CREATE PROCEDURE [dbo].[TaskScheduleGetByID]
	@TaskScheduleID		int
AS
	SELECT	TaskScheduleID,
		StartTime,
		EndTime,
		RetryCount,
		MinRetryDelay,
		RepeatDelay,
		NumParallelTasks,
		SleepBetweenTasks
	FROM	[dbo].[TaskSchedule]
	WHERE	TaskScheduleID = @TaskScheduleID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[TaskScheduleGetAll]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[TaskScheduleGetAll]
GO
CREATE PROCEDURE [dbo].[TaskScheduleGetAll]
AS
	SELECT	TaskScheduleID,
		StartTime,
		EndTime,
		RetryCount,
		MinRetryDelay,
		RepeatDelay,
		NumParallelTasks,
		SleepBetweenTasks
	FROM	[dbo].[TaskSchedule]
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[TaskScheduleAdd]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[TaskScheduleAdd]
GO
CREATE PROCEDURE [dbo].[TaskScheduleAdd]
	@StartTime		datetime = NULL,
	@EndTime		datetime = NULL,
	@RetryCount		int = 1,
	@MinRetryDelay		int = 60,
	@RepeatDelay		int = 86400,
	@NumParallelTasks	int = 1,
	@SleepBetweenTasks	int = 0
AS
	INSERT INTO  dbo.TaskSchedule (
		StartTime,
		EndTime,
		RetryCount,
		MinRetryDelay,
		RepeatDelay,
		NumParallelTasks,
		SleepBetweenTasks
	)
	VALUES (
		@StartTime,
		@EndTime,
		@RetryCount,
		@MinRetryDelay,
		@RepeatDelay,
		@NumParallelTasks,
		@SleepBetweenTasks
	)
	RETURN SCOPE_IDENTITY()
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[TaskScheduleSchema]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[TaskScheduleSchema]
GO
CREATE PROCEDURE [dbo].[TaskScheduleSchema]
AS
	SELECT
	'IF OBJECT_ID(''tempdb..#TaskSchedule'') IS NULL' + CAST(0x0A AS CHAR(1)) +
	'	CREATE TABLE #TaskSchedule (' + CAST(0x0A AS CHAR(1)) +
	'		TaskScheduleID		int NULL,' + CAST(0x0A AS CHAR(1)) +
	'		StartTime		datetime NULL,' + CAST(0x0A AS CHAR(1)) +
	'		EndTime			datetime NULL,' + CAST(0x0A AS CHAR(1)) +
	'		RetryCount		int NULL DEFAULT 1,' + CAST(0x0A AS CHAR(1)) +
	'		MinRetryDelay		int NULL DEFAULT 60,' + CAST(0x0A AS CHAR(1)) +
	'		RepeatDelay		int NULL DEFAULT 24 * 3600,' + CAST(0x0A AS CHAR(1)) +
	'		NumParallelTasks	int NULL DEFAULT 1,' + CAST(0x0A AS CHAR(1)) +
	'		SleepBetweenTasks	int NULL DEFAULT 0' + CAST(0x0A AS CHAR(1)) +
	'	)' + CAST(0x0A AS CHAR(1)) +
	'ELSE' + CAST(0x0A AS CHAR(1)) +
	'	DELETE FROM #TaskSchedule' + CAST(0x0A AS CHAR(1)) +
	'' AS SQL
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[TaskScheduleTempAdd]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[TaskScheduleTempAdd]
GO
CREATE PROCEDURE dbo.[TaskScheduleTempAdd]
	@TaskScheduleID		int,
	@StartTime		datetime = NULL,
	@EndTime		datetime = NULL,
	@RetryCount		int = 1,
	@MinRetryDelay		int = 60,
	@RepeatDelay		int = 86400,
	@NumParallelTasks	int = 1,
	@SleepBetweenTasks	int = 0
AS
	INSERT INTO #TaskSchedule (
		TaskScheduleID,
		StartTime,
		EndTime,
		RetryCount,
		MinRetryDelay,
		RepeatDelay,
		NumParallelTasks,
		SleepBetweenTasks
	)
	VALUES (
		@TaskScheduleID,
		@StartTime,
		@EndTime,
		@RetryCount,
		@MinRetryDelay,
		@RepeatDelay,
		@NumParallelTasks,
		@SleepBetweenTasks
	)
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[TaskScheduleAddBatch]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[TaskScheduleAddBatch]
GO
CREATE PROCEDURE dbo.[TaskScheduleAddBatch]
AS
	DECLARE @count int
	INSERT dbo.TaskSchedule (
		StartTime,
		EndTime,
		RetryCount,
		MinRetryDelay,
		RepeatDelay,
		NumParallelTasks,
		SleepBetweenTasks
	)
		SELECT	StartTime,
			EndTime,
			RetryCount,
			MinRetryDelay,
			RepeatDelay,
			NumParallelTasks,
			SleepBetweenTasks
		FROM #TaskSchedule
	SET @count = @@ROWCOUNT
	DROP TABLE #TaskSchedule	-- Drop temporary table
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[TaskScheduleUpdateByID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[TaskScheduleUpdateByID]
GO
CREATE PROCEDURE [dbo].[TaskScheduleUpdateByID]
	@TaskScheduleID		int,
	@StartTime		datetime = NULL,
	@EndTime		datetime = NULL,
	@RetryCount		int = 1,
	@MinRetryDelay		int = 60,
	@RepeatDelay		int = 86400,
	@NumParallelTasks	int = 1,
	@SleepBetweenTasks	int = 0
AS
	DECLARE	@ID	int
	SET @ID = 0

	UPDATE	[dbo].[TaskSchedule]
	SET	@ID = TaskScheduleID,
		StartTime = @StartTime,
		EndTime = @EndTime,
		RetryCount = @RetryCount,
		MinRetryDelay = @MinRetryDelay,
		RepeatDelay = @RepeatDelay,
		NumParallelTasks = @NumParallelTasks,
		SleepBetweenTasks = @SleepBetweenTasks
	WHERE	TaskScheduleID = @TaskScheduleID
	RETURN @ID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[TaskScheduleUpdateBatchByID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[TaskScheduleUpdateBatchByID]
GO
CREATE PROCEDURE dbo.[TaskScheduleUpdateBatchByID]
AS
	DECLARE @count int

	CREATE INDEX [TempTaskScheduleID]
		ON #TaskSchedule (TaskScheduleID)

	UPDATE	[dbo].[TaskSchedule]
	SET	StartTime = t.StartTime,
		EndTime = t.EndTime,
		RetryCount = t.RetryCount,
		MinRetryDelay = t.MinRetryDelay,
		RepeatDelay = t.RepeatDelay,
		NumParallelTasks = t.NumParallelTasks,
		SleepBetweenTasks = t.SleepBetweenTasks
	FROM	#TaskSchedule AS t
	WHERE	TaskSchedule.TaskScheduleID = t.TaskScheduleID
	SET @count = @@ROWCOUNT
	DROP TABLE #TaskSchedule	-- Drop the temporary table
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[TaskScheduleRemoveBatch]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[TaskScheduleRemoveBatch]
GO

CREATE PROCEDURE [dbo].[TaskScheduleRemoveBatch]
AS

	CREATE INDEX [TempTaskScheduleTaskScheduleRemoveBatch]
		ON #TaskSchedule (TaskScheduleID)	

	-- Delete records from TaskSchedule identified by fields of [TempTaskScheduleTaskScheduleRemoveBatch]
	DELETE [dbo].[TaskSchedule]
	WHERE EXISTS(
			SELECT * FROM #TaskSchedule AS t
			WHERE	TaskSchedule.TaskScheduleID = t.TaskScheduleID
		)
	DROP TABLE #TaskSchedule      -- Drop the temporary table
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[TaskScheduleRemoveByID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[TaskScheduleRemoveByID]
GO
CREATE PROCEDURE [dbo].[TaskScheduleRemoveByID]
	@TaskScheduleID		int
AS
	DELETE	[dbo].[TaskSchedule]
	WHERE	TaskScheduleID = @TaskScheduleID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[TaskScheduleRemoveAll]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[TaskScheduleRemoveAll]
GO
CREATE PROCEDURE [dbo].[TaskScheduleRemoveAll]
	
AS
	DELETE	[dbo].[TaskSchedule]
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[TaskGetByID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[TaskGetByID]
GO
CREATE PROCEDURE [dbo].[TaskGetByID]
	@TaskID			int
AS
	SELECT	TaskID,
		TaskUID,
		TaskTypeID,
		TaskName,
		PackagePathID,
		TaskScheduleID,
		MinimumVersion
	FROM	[dbo].[Task]
	WHERE	TaskID = @TaskID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[TaskGetAllByUID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[TaskGetAllByUID]
GO
CREATE PROCEDURE [dbo].[TaskGetAllByUID]
	@TaskUID		binary(16) = NULL
AS
	SELECT	TaskID,
		TaskUID,
		TaskTypeID,
		TaskName,
		PackagePathID,
		TaskScheduleID,
		MinimumVersion
	FROM	[dbo].[Task]
	WHERE	(TaskUID = @TaskUID OR (TaskUID IS NULL AND @TaskUID IS NULL))
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[TaskGetByName]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[TaskGetByName]
GO
CREATE PROCEDURE [dbo].[TaskGetByName]
	@TaskName		nvarchar(128)
AS
	SELECT	TaskID,
		TaskUID,
		TaskTypeID,
		TaskName,
		PackagePathID,
		TaskScheduleID,
		MinimumVersion
	FROM	[dbo].[Task]
	WHERE	TaskName = @TaskName
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[TaskGetAll]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[TaskGetAll]
GO
CREATE PROCEDURE [dbo].[TaskGetAll]
AS
	SELECT	TaskID,
		TaskUID,
		TaskTypeID,
		TaskName,
		PackagePathID,
		TaskScheduleID,
		MinimumVersion
	FROM	[dbo].[Task]
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[TaskAdd]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[TaskAdd]
GO
CREATE PROCEDURE [dbo].[TaskAdd]
	@TaskUID		binary(16) = NULL,
	@TaskTypeID		int,
	@TaskName		nvarchar(128),
	@PackagePathID		int = NULL,
	@TaskScheduleID		int,
	@MinimumVersion		nvarchar(16) = NULL
AS
	INSERT INTO  dbo.Task (
		TaskUID,
		TaskTypeID,
		TaskName,
		PackagePathID,
		TaskScheduleID,
		MinimumVersion
	)
	VALUES (
		@TaskUID,
		@TaskTypeID,
		@TaskName,
		@PackagePathID,
		@TaskScheduleID,
		@MinimumVersion
	)
	RETURN SCOPE_IDENTITY()
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[TaskBind]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[TaskBind]
GO
CREATE PROCEDURE [dbo].[TaskBind]
	@TaskUID		binary(16) = NULL,
	@TaskTypeID		int,
	@TaskName		nvarchar(128),
	@PackagePathID		int = NULL,
	@TaskScheduleID		int,
	@MinimumVersion		nvarchar(16) = NULL
AS
	DECLARE	@ID	int

	SELECT	@ID = TaskID
	FROM	[dbo].[Task]
	WHERE	TaskName = @TaskName

	IF @ID IS NULL
		EXEC @ID = TaskAdd @TaskUID,
			@TaskTypeID,
			@TaskName,
			@PackagePathID,
			@TaskScheduleID,
			@MinimumVersion

	RETURN @ID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[TaskSchema]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[TaskSchema]
GO
CREATE PROCEDURE [dbo].[TaskSchema]
AS
	SELECT
	'IF OBJECT_ID(''tempdb..#Task'') IS NULL' + CAST(0x0A AS CHAR(1)) +
	'	CREATE TABLE #Task (' + CAST(0x0A AS CHAR(1)) +
	'		TaskID			int NULL,' + CAST(0x0A AS CHAR(1)) +
	'		TaskUID			binary(16) NULL,' + CAST(0x0A AS CHAR(1)) +
	'		TaskTypeID		int NOT NULL,' + CAST(0x0A AS CHAR(1)) +
	'		TaskName		nvarchar(128) COLLATE database_default NOT NULL,' + CAST(0x0A AS CHAR(1)) +
	'		PackagePathID		int NULL,' + CAST(0x0A AS CHAR(1)) +
	'		TaskScheduleID		int NOT NULL,' + CAST(0x0A AS CHAR(1)) +
	'		MinimumVersion		nvarchar(16) COLLATE database_default NULL' + CAST(0x0A AS CHAR(1)) +
	'	)' + CAST(0x0A AS CHAR(1)) +
	'ELSE' + CAST(0x0A AS CHAR(1)) +
	'	DELETE FROM #Task' + CAST(0x0A AS CHAR(1)) +
	'' AS SQL
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[TaskTempAdd]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[TaskTempAdd]
GO
CREATE PROCEDURE dbo.[TaskTempAdd]
	@TaskID			int,
	@TaskUID		binary(16) = NULL,
	@TaskTypeID		int,
	@TaskName		nvarchar(128),
	@PackagePathID		int = NULL,
	@TaskScheduleID		int,
	@MinimumVersion		nvarchar(16) = NULL
AS
	INSERT INTO #Task (
		TaskID,
		TaskUID,
		TaskTypeID,
		TaskName,
		PackagePathID,
		TaskScheduleID,
		MinimumVersion
	)
	VALUES (
		@TaskID,
		@TaskUID,
		@TaskTypeID,
		@TaskName,
		@PackagePathID,
		@TaskScheduleID,
		@MinimumVersion
	)
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[TaskAddBatch]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[TaskAddBatch]
GO
CREATE PROCEDURE dbo.[TaskAddBatch]
AS
	DECLARE @count int
	INSERT dbo.Task (
		TaskUID,
		TaskTypeID,
		TaskName,
		PackagePathID,
		TaskScheduleID,
		MinimumVersion
	)
		SELECT	TaskUID,
			TaskTypeID,
			TaskName,
			PackagePathID,
			TaskScheduleID,
			MinimumVersion
		FROM #Task
	SET @count = @@ROWCOUNT
	DROP TABLE #Task	-- Drop temporary table
	RETURN @count
GO

/*
Add new Task bound to
	TaskType using TaskTypeName
	with TaskUID, TaskName, PackagePathID, TaskScheduleID, MinimumVersion
*/

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[TaskUpdateByID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[TaskUpdateByID]
GO
CREATE PROCEDURE [dbo].[TaskUpdateByID]
	@TaskID			int,
	@TaskUID		binary(16) = NULL,
	@TaskTypeID		int,
	@TaskName		nvarchar(128),
	@PackagePathID		int = NULL,
	@TaskScheduleID		int,
	@MinimumVersion		nvarchar(16) = NULL
AS
	DECLARE	@ID	int
	SET @ID = 0

	UPDATE	[dbo].[Task]
	SET	@ID = TaskID,
		TaskUID = @TaskUID,
		TaskTypeID = @TaskTypeID,
		TaskName = @TaskName,
		PackagePathID = @PackagePathID,
		TaskScheduleID = @TaskScheduleID,
		MinimumVersion = @MinimumVersion
	WHERE	TaskID = @TaskID
	RETURN @ID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[TaskUpdateBatchByID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[TaskUpdateBatchByID]
GO
CREATE PROCEDURE dbo.[TaskUpdateBatchByID]
AS
	DECLARE @count int

	CREATE INDEX [TempTaskID]
		ON #Task (TaskID)

	UPDATE	[dbo].[Task]
	SET	TaskUID = t.TaskUID,
		TaskTypeID = t.TaskTypeID,
		TaskName = t.TaskName,
		PackagePathID = t.PackagePathID,
		TaskScheduleID = t.TaskScheduleID,
		MinimumVersion = t.MinimumVersion
	FROM	#Task AS t
	WHERE	Task.TaskID = t.TaskID
	SET @count = @@ROWCOUNT
	DROP TABLE #Task	-- Drop the temporary table
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[TaskUpdateByName]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[TaskUpdateByName]
GO
CREATE PROCEDURE [dbo].[TaskUpdateByName]
	@TaskName		nvarchar(128),
	@TaskUID		binary(16) = NULL,
	@TaskTypeID		int,
	@PackagePathID		int = NULL,
	@TaskScheduleID		int,
	@MinimumVersion		nvarchar(16) = NULL
AS
	DECLARE	@ID	int
	SET @ID = 0

	UPDATE	[dbo].[Task]
	SET	@ID = TaskID,
		TaskUID = @TaskUID,
		TaskTypeID = @TaskTypeID,
		PackagePathID = @PackagePathID,
		TaskScheduleID = @TaskScheduleID,
		MinimumVersion = @MinimumVersion
	WHERE	TaskName = @TaskName
	RETURN @ID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[TaskUpdateBatchByName]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[TaskUpdateBatchByName]
GO
CREATE PROCEDURE dbo.[TaskUpdateBatchByName]
AS
	DECLARE @count int

	CREATE INDEX [TempTaskName]
		ON #Task (TaskName)

	UPDATE	[dbo].[Task]
	SET	TaskUID = t.TaskUID,
		TaskTypeID = t.TaskTypeID,
		PackagePathID = t.PackagePathID,
		TaskScheduleID = t.TaskScheduleID,
		MinimumVersion = t.MinimumVersion
	FROM	#Task AS t
	WHERE	Task.TaskName = t.TaskName
	SET @count = @@ROWCOUNT
	DROP TABLE #Task	-- Drop the temporary table
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[TaskPutByName]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[TaskPutByName]
GO
CREATE PROCEDURE [dbo].[TaskPutByName]
	@TaskName		nvarchar(128),
	@TaskUID		binary(16) = NULL,
	@TaskTypeID		int,
	@PackagePathID		int = NULL,
	@TaskScheduleID		int,
	@MinimumVersion		nvarchar(16) = NULL
AS
	DECLARE @ID	int

	SELECT	@ID = TaskID
	FROM	Task
	WHERE	TaskName = @TaskName

	IF @ID IS NULL
		EXEC @ID = TaskAdd @TaskUID,
			@TaskTypeID,
			@TaskName,
			@PackagePathID,
			@TaskScheduleID,
			@MinimumVersion
	ELSE
		EXEC TaskUpdateByName @TaskName,
			@TaskUID,
			@TaskTypeID,
			@PackagePathID,
			@TaskScheduleID,
			@MinimumVersion

	RETURN @ID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[TaskPutBatchByName]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[TaskPutBatchByName]
GO
CREATE PROCEDURE [dbo].[TaskPutBatchByName]
AS
	DECLARE @count AS int
	SET @count = 0

	CREATE INDEX [TempTaskName]
		ON #Task (TaskName)

	BEGIN TRANSACTION
	UPDATE [dbo].[Task]
		SET	TaskUID = t.TaskUID,
			TaskTypeID = t.TaskTypeID,
			PackagePathID = t.PackagePathID,
			TaskScheduleID = t.TaskScheduleID,
			MinimumVersion = t.MinimumVersion
		FROM	#Task AS t
		WHERE	Task.TaskName = t.TaskName
	SET @count = @@ROWCOUNT

	INSERT [dbo].[Task] (
		TaskUID,
		TaskTypeID,
		TaskName,
		PackagePathID,
		TaskScheduleID,
		MinimumVersion
	)
		SELECT	TaskUID,
			TaskTypeID,
			TaskName,
			PackagePathID,
			TaskScheduleID,
			MinimumVersion
		FROM	#Task AS t
		WHERE NOT EXISTS(	-- Current record doesn't exist
			SELECT * FROM [dbo].[Task]
			WHERE	Task.TaskName = t.TaskName
		)
	SET @count = @count + @@ROWCOUNT
	DROP TABLE #Task	-- Drop the temporary table
	COMMIT WORK
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[TaskRemoveBatch]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[TaskRemoveBatch]
GO

CREATE PROCEDURE [dbo].[TaskRemoveBatch]
AS

	CREATE INDEX [TempTaskTaskRemoveBatch]
		ON #Task (TaskID)	

	-- Delete records from Task identified by fields of [TempTaskTaskRemoveBatch]
	DELETE [dbo].[Task]
	WHERE EXISTS(
			SELECT * FROM #Task AS t
			WHERE	Task.TaskID = t.TaskID
		)
	DROP TABLE #Task      -- Drop the temporary table
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[TaskRemoveByID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[TaskRemoveByID]
GO
CREATE PROCEDURE [dbo].[TaskRemoveByID]
	@TaskID			int
AS
	-- Task deletes cascade to:
	--	Job by FK_Job_Task
	--		Action by FK_Action_Job
	--			ActionApplies by FK_ActionApplies_Action
	-- Task deletes may fail due to non-cascading FKs:
	--	Action by FK_Action_Task
	DELETE	[dbo].[Task]
	WHERE	TaskID = @TaskID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[TaskRemoveAllByUID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[TaskRemoveAllByUID]
GO
CREATE PROCEDURE [dbo].[TaskRemoveAllByUID]
	@TaskUID		binary(16) = NULL
AS
	DELETE	[dbo].[Task]
	WHERE	(TaskUID = @TaskUID OR (TaskUID IS NULL AND @TaskUID IS NULL))
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[TaskRemoveByName]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[TaskRemoveByName]
GO
CREATE PROCEDURE [dbo].[TaskRemoveByName]
	@TaskName		nvarchar(128)
AS
	-- Task deletes cascade to:
	--	Job by FK_Job_Task
	--		Action by FK_Action_Job
	--			ActionApplies by FK_ActionApplies_Action
	-- Task deletes may fail due to non-cascading FKs:
	--	Action by FK_Action_Task
	DELETE	[dbo].[Task]
	WHERE	TaskName = @TaskName
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[TaskRemoveAll]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[TaskRemoveAll]
GO
CREATE PROCEDURE [dbo].[TaskRemoveAll]
	
AS
	DELETE	[dbo].[Task]
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[JobGetAllByTaskID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[JobGetAllByTaskID]
GO
CREATE PROCEDURE [dbo].[JobGetAllByTaskID]
	@TaskID			int
AS
	SELECT	JobUID,
		TaskID,
		ServerUID
	FROM	[dbo].[Job]
	WHERE	TaskID = @TaskID
	ORDER BY ServerUID
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[JobGetByUID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[JobGetByUID]
GO
CREATE PROCEDURE [dbo].[JobGetByUID]
	@JobUID			binary(16)
AS
	SELECT	JobUID,
		TaskID,
		ServerUID
	FROM	[dbo].[Job]
	WHERE	JobUID = @JobUID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[JobGetAll]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[JobGetAll]
GO
CREATE PROCEDURE [dbo].[JobGetAll]
AS
	SELECT	JobUID,
		TaskID,
		ServerUID
	FROM	[dbo].[Job]
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[JobAdd]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[JobAdd]
GO
CREATE PROCEDURE [dbo].[JobAdd]
	@JobUID			binary(16),
	@TaskID			int,
	@ServerUID		binary(16)
AS
	INSERT INTO  dbo.Job (
		JobUID,
		TaskID,
		ServerUID
	)
	VALUES (
		@JobUID,
		@TaskID,
		@ServerUID
	)
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[JobSchema]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[JobSchema]
GO
CREATE PROCEDURE [dbo].[JobSchema]
AS
	SELECT
	'IF OBJECT_ID(''tempdb..#Job'') IS NULL' + CAST(0x0A AS CHAR(1)) +
	'	CREATE TABLE #Job (' + CAST(0x0A AS CHAR(1)) +
	'		JobUID			binary(16) NOT NULL,' + CAST(0x0A AS CHAR(1)) +
	'		TaskID			int NOT NULL,' + CAST(0x0A AS CHAR(1)) +
	'		ServerUID		binary(16) NOT NULL' + CAST(0x0A AS CHAR(1)) +
	'	)' + CAST(0x0A AS CHAR(1)) +
	'ELSE' + CAST(0x0A AS CHAR(1)) +
	'	DELETE FROM #Job' + CAST(0x0A AS CHAR(1)) +
	'' AS SQL
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[JobTempAdd]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[JobTempAdd]
GO
CREATE PROCEDURE dbo.[JobTempAdd]
	@JobUID			binary(16),
	@TaskID			int,
	@ServerUID		binary(16)
AS
	INSERT INTO #Job (
		JobUID,
		TaskID,
		ServerUID
	)
	VALUES (
		@JobUID,
		@TaskID,
		@ServerUID
	)
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[JobAddBatch]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[JobAddBatch]
GO
CREATE PROCEDURE dbo.[JobAddBatch]
AS
	DECLARE @count int
	INSERT dbo.Job (
		JobUID,
		TaskID,
		ServerUID
	)
		SELECT	JobUID,
			TaskID,
			ServerUID
		FROM #Job
	SET @count = @@ROWCOUNT
	DROP TABLE #Job	-- Drop temporary table
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[JobUpdateByTaskIDServerUID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[JobUpdateByTaskIDServerUID]
GO
CREATE PROCEDURE [dbo].[JobUpdateByTaskIDServerUID]
	@TaskID			int,
	@ServerUID		binary(16),
	@JobUID			binary(16)
AS
	UPDATE	[dbo].[Job]
	SET	JobUID = @JobUID
	WHERE	TaskID = @TaskID
	  AND	ServerUID = @ServerUID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[JobUpdateBatchByTaskIDServerUID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[JobUpdateBatchByTaskIDServerUID]
GO
CREATE PROCEDURE dbo.[JobUpdateBatchByTaskIDServerUID]
AS
	DECLARE @count int

	CREATE INDEX [TempJobTaskIDServerUID]
		ON #Job (TaskID, ServerUID)

	UPDATE	[dbo].[Job]
	SET	JobUID = t.JobUID
	FROM	#Job AS t
	WHERE	Job.TaskID = t.TaskID
	  AND	Job.ServerUID = t.ServerUID
	SET @count = @@ROWCOUNT
	DROP TABLE #Job	-- Drop the temporary table
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[JobPutByTaskIDServerUID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[JobPutByTaskIDServerUID]
GO
CREATE PROCEDURE [dbo].[JobPutByTaskIDServerUID]
	@TaskID			int,
	@ServerUID		binary(16),
	@JobUID			binary(16)
AS
	IF NOT EXISTS(
		SELECT	1
		FROM	dbo.Job
		WHERE	TaskID = @TaskID
		  AND	ServerUID = @ServerUID
	)
		EXEC JobAdd @JobUID,
			@TaskID,
			@ServerUID
	ELSE
		EXEC JobUpdateByTaskIDServerUID @TaskID,
			@ServerUID,
			@JobUID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[JobPutBatchByTaskIDServerUID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[JobPutBatchByTaskIDServerUID]
GO
CREATE PROCEDURE [dbo].[JobPutBatchByTaskIDServerUID]
AS
	DECLARE @count AS int
	SET @count = 0

	CREATE INDEX [TempJobTaskIDServerUID]
		ON #Job (TaskID, ServerUID)

	BEGIN TRANSACTION
	UPDATE [dbo].[Job]
		SET	JobUID = t.JobUID
		FROM	#Job AS t
		WHERE	Job.TaskID = t.TaskID
		  AND	Job.ServerUID = t.ServerUID
	SET @count = @@ROWCOUNT

	INSERT [dbo].[Job] (
		JobUID,
		TaskID,
		ServerUID
	)
		SELECT	JobUID,
			TaskID,
			ServerUID
		FROM	#Job AS t
		WHERE NOT EXISTS(	-- Current record doesn't exist
			SELECT * FROM [dbo].[Job]
			WHERE	Job.TaskID = t.TaskID
			  AND	Job.ServerUID = t.ServerUID
		)
	SET @count = @count + @@ROWCOUNT
	DROP TABLE #Job	-- Drop the temporary table
	COMMIT WORK
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[JobRemoveBatch]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[JobRemoveBatch]
GO

CREATE PROCEDURE [dbo].[JobRemoveBatch]
AS

	CREATE INDEX [TempJobJobRemoveBatch]
		ON #Job (TaskID, ServerUID)	

	-- Delete records from Job identified by fields of [TempJobJobRemoveBatch]
	DELETE [dbo].[Job]
	WHERE EXISTS(
			SELECT * FROM #Job AS t
			WHERE	Job.TaskID = t.TaskID
			  AND	Job.ServerUID = t.ServerUID
		)
	DROP TABLE #Job      -- Drop the temporary table
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[JobRemoveByTaskIDServerUID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[JobRemoveByTaskIDServerUID]
GO
CREATE PROCEDURE [dbo].[JobRemoveByTaskIDServerUID]
	@TaskID			int,
	@ServerUID		binary(16)
AS
	-- Job deletes cascade to:
	--	Action by FK_Action_Job
	--		ActionApplies by FK_ActionApplies_Action
	DELETE	[dbo].[Job]
	WHERE	TaskID = @TaskID
	  AND	ServerUID = @ServerUID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[JobRemoveAll]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[JobRemoveAll]
GO
CREATE PROCEDURE [dbo].[JobRemoveAll]
	
AS
	DELETE	[dbo].[Job]
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ActionStateGetByID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ActionStateGetByID]
GO
CREATE PROCEDURE [dbo].[ActionStateGetByID]
	@ActionStateID		int
AS
	SELECT	ActionStateID,
		ActionStateName
	FROM	[dbo].[ActionState]
	WHERE	ActionStateID = @ActionStateID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ActionStateGetByName]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ActionStateGetByName]
GO
CREATE PROCEDURE [dbo].[ActionStateGetByName]
	@ActionStateName	nvarchar(32)
AS
	SELECT	ActionStateID,
		ActionStateName
	FROM	[dbo].[ActionState]
	WHERE	ActionStateName = @ActionStateName
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ActionStateGetAll]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ActionStateGetAll]
GO
CREATE PROCEDURE [dbo].[ActionStateGetAll]
AS
	SELECT	ActionStateID,
		ActionStateName
	FROM	[dbo].[ActionState]
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ActionStateBind]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ActionStateBind]
GO
CREATE PROCEDURE [dbo].[ActionStateBind]
	@ActionStateName	nvarchar(32)
AS
	DECLARE	@ID	int

	SELECT	@ID = ActionStateID
	FROM	[dbo].[ActionState]
	WHERE	ActionStateName = @ActionStateName

	RETURN @ID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ActionGetByUID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ActionGetByUID]
GO
CREATE PROCEDURE [dbo].[ActionGetByUID]
	@ActionUID		binary(16)
AS
	SELECT	ActionUID,
		TaskID,
		ServerUID,
		JobUID,
		ActionStateID,
		PackageVersionID,
		FailureReason,
		LastUpdate,
		DSVersion
	FROM	[dbo].[Action]
	WHERE	ActionUID = @ActionUID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ActionGetByTaskIDServerUID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ActionGetByTaskIDServerUID]
GO
CREATE PROCEDURE [dbo].[ActionGetByTaskIDServerUID]
	@TaskID			int,
	@ServerUID		binary(16) = NULL
AS
	SELECT	ActionUID,
		TaskID,
		ServerUID,
		JobUID,
		ActionStateID,
		PackageVersionID,
		FailureReason,
		LastUpdate,
		DSVersion
	FROM	[dbo].[Action]
	WHERE	TaskID = @TaskID
	  AND	(ServerUID = @ServerUID OR (ServerUID IS NULL AND @ServerUID IS NULL))
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ActionGetAllByTaskID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ActionGetAllByTaskID]
GO
CREATE PROCEDURE [dbo].[ActionGetAllByTaskID]
	@TaskID			int
AS
	SELECT	ActionUID,
		TaskID,
		ServerUID,
		JobUID,
		ActionStateID,
		PackageVersionID,
		FailureReason,
		LastUpdate,
		DSVersion
	FROM	[dbo].[Action]
	WHERE	TaskID = @TaskID
	ORDER BY ServerUID
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ActionGetAll]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ActionGetAll]
GO
CREATE PROCEDURE [dbo].[ActionGetAll]
AS
	SELECT	ActionUID,
		TaskID,
		ServerUID,
		JobUID,
		ActionStateID,
		PackageVersionID,
		FailureReason,
		LastUpdate,
		DSVersion
	FROM	[dbo].[Action]
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ActionAdd]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ActionAdd]
GO
CREATE PROCEDURE [dbo].[ActionAdd]
	@ActionUID		binary(16),
	@TaskID			int,
	@ServerUID		binary(16) = NULL,
	@JobUID			binary(16) = NULL,
	@ActionStateID		int,
	@PackageVersionID	int = NULL,
	@FailureReason		ntext = NULL,
	@LastUpdate		datetime,
	@DSVersion		nvarchar(32) = NULL
AS
	INSERT INTO  dbo.Action (
		ActionUID,
		TaskID,
		ServerUID,
		JobUID,
		ActionStateID,
		PackageVersionID,
		FailureReason,
		LastUpdate,
		DSVersion
	)
	VALUES (
		@ActionUID,
		@TaskID,
		@ServerUID,
		@JobUID,
		@ActionStateID,
		@PackageVersionID,
		@FailureReason,
		@LastUpdate,
		@DSVersion
	)
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ActionSchema]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ActionSchema]
GO
CREATE PROCEDURE [dbo].[ActionSchema]
AS
	SELECT
	'IF OBJECT_ID(''tempdb..#Action'') IS NULL' + CAST(0x0A AS CHAR(1)) +
	'	CREATE TABLE #Action (' + CAST(0x0A AS CHAR(1)) +
	'		ActionUID		binary(16) NOT NULL,' + CAST(0x0A AS CHAR(1)) +
	'		TaskID			int NOT NULL,' + CAST(0x0A AS CHAR(1)) +
	'		ServerUID		binary(16) NULL,' + CAST(0x0A AS CHAR(1)) +
	'		JobUID			binary(16) NULL,' + CAST(0x0A AS CHAR(1)) +
	'		ActionStateID		int NOT NULL,' + CAST(0x0A AS CHAR(1)) +
	'		PackageVersionID	int NULL,' + CAST(0x0A AS CHAR(1)) +
	'		FailureReason		ntext COLLATE database_default NULL,' + CAST(0x0A AS CHAR(1)) +
	'		LastUpdate		datetime NOT NULL DEFAULT getdate(),' + CAST(0x0A AS CHAR(1)) +
	'		DSVersion		nvarchar(32) COLLATE database_default NULL' + CAST(0x0A AS CHAR(1)) +
	'	)' + CAST(0x0A AS CHAR(1)) +
	'ELSE' + CAST(0x0A AS CHAR(1)) +
	'	DELETE FROM #Action' + CAST(0x0A AS CHAR(1)) +
	'' AS SQL
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ActionTempAdd]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ActionTempAdd]
GO
CREATE PROCEDURE dbo.[ActionTempAdd]
	@ActionUID		binary(16),
	@TaskID			int,
	@ServerUID		binary(16) = NULL,
	@JobUID			binary(16) = NULL,
	@ActionStateID		int,
	@PackageVersionID	int = NULL,
	@FailureReason		ntext = NULL,
	@LastUpdate		datetime,
	@DSVersion		nvarchar(32) = NULL
AS
	INSERT INTO #Action (
		ActionUID,
		TaskID,
		ServerUID,
		JobUID,
		ActionStateID,
		PackageVersionID,
		FailureReason,
		LastUpdate,
		DSVersion
	)
	VALUES (
		@ActionUID,
		@TaskID,
		@ServerUID,
		@JobUID,
		@ActionStateID,
		@PackageVersionID,
		@FailureReason,
		@LastUpdate,
		@DSVersion
	)
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ActionAddBatch]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ActionAddBatch]
GO
CREATE PROCEDURE dbo.[ActionAddBatch]
AS
	DECLARE @count int
	INSERT dbo.Action (
		ActionUID,
		TaskID,
		ServerUID,
		JobUID,
		ActionStateID,
		PackageVersionID,
		FailureReason,
		LastUpdate,
		DSVersion
	)
		SELECT	ActionUID,
			TaskID,
			ServerUID,
			JobUID,
			ActionStateID,
			PackageVersionID,
			FailureReason,
			LastUpdate,
			DSVersion
		FROM #Action
	SET @count = @@ROWCOUNT
	DROP TABLE #Action	-- Drop temporary table
	RETURN @count
GO

/*
Add new Action bound to
	ActionState using ActionStateName
	with ActionUID, TaskID, ServerUID, JobUID, PackageVersionID, FailureReason, LastUpdate, DSVersion
*/

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ActionUpdateByUID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ActionUpdateByUID]
GO
CREATE PROCEDURE [dbo].[ActionUpdateByUID]
	@ActionUID		binary(16),
	@TaskID			int,
	@ServerUID		binary(16) = NULL,
	@JobUID			binary(16) = NULL,
	@ActionStateID		int,
	@PackageVersionID	int = NULL,
	@FailureReason		ntext = NULL,
	@LastUpdate		datetime,
	@DSVersion		nvarchar(32) = NULL
AS
	UPDATE	[dbo].[Action]
	SET	TaskID = @TaskID,
		ServerUID = @ServerUID,
		JobUID = @JobUID,
		ActionStateID = @ActionStateID,
		PackageVersionID = @PackageVersionID,
		FailureReason = @FailureReason,
		LastUpdate = @LastUpdate,
		DSVersion = @DSVersion
	WHERE	ActionUID = @ActionUID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ActionUpdateBatchByUID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ActionUpdateBatchByUID]
GO
CREATE PROCEDURE dbo.[ActionUpdateBatchByUID]
AS
	DECLARE @count int

	CREATE INDEX [TempActionUID]
		ON #Action (ActionUID)

	UPDATE	[dbo].[Action]
	SET	TaskID = t.TaskID,
		ServerUID = t.ServerUID,
		JobUID = t.JobUID,
		ActionStateID = t.ActionStateID,
		PackageVersionID = t.PackageVersionID,
		FailureReason = t.FailureReason,
		LastUpdate = t.LastUpdate,
		DSVersion = t.DSVersion
	FROM	#Action AS t
	WHERE	Action.ActionUID = t.ActionUID
	SET @count = @@ROWCOUNT
	DROP TABLE #Action	-- Drop the temporary table
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ActionPutByUID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ActionPutByUID]
GO
CREATE PROCEDURE [dbo].[ActionPutByUID]
	@ActionUID		binary(16),
	@TaskID			int,
	@ServerUID		binary(16) = NULL,
	@JobUID			binary(16) = NULL,
	@ActionStateID		int,
	@PackageVersionID	int = NULL,
	@FailureReason		ntext = NULL,
	@LastUpdate		datetime,
	@DSVersion		nvarchar(32) = NULL
AS
	IF NOT EXISTS(
		SELECT	1
		FROM	dbo.Action
		WHERE	ActionUID = @ActionUID
	)
		EXEC ActionAdd @ActionUID,
			@TaskID,
			@ServerUID,
			@JobUID,
			@ActionStateID,
			@PackageVersionID,
			@FailureReason,
			@LastUpdate,
			@DSVersion
	ELSE
		EXEC ActionUpdateByUID @ActionUID,
			@TaskID,
			@ServerUID,
			@JobUID,
			@ActionStateID,
			@PackageVersionID,
			@FailureReason,
			@LastUpdate,
			@DSVersion
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ActionPutBatchByUID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ActionPutBatchByUID]
GO
CREATE PROCEDURE [dbo].[ActionPutBatchByUID]
AS
	DECLARE @count AS int
	SET @count = 0

	CREATE INDEX [TempActionUID]
		ON #Action (ActionUID)

	BEGIN TRANSACTION
	UPDATE [dbo].[Action]
		SET	TaskID = t.TaskID,
			ServerUID = t.ServerUID,
			JobUID = t.JobUID,
			ActionStateID = t.ActionStateID,
			PackageVersionID = t.PackageVersionID,
			FailureReason = t.FailureReason,
			LastUpdate = t.LastUpdate,
			DSVersion = t.DSVersion
		FROM	#Action AS t
		WHERE	Action.ActionUID = t.ActionUID
	SET @count = @@ROWCOUNT

	INSERT [dbo].[Action] (
		ActionUID,
		TaskID,
		ServerUID,
		JobUID,
		ActionStateID,
		PackageVersionID,
		FailureReason,
		LastUpdate,
		DSVersion
	)
		SELECT	ActionUID,
			TaskID,
			ServerUID,
			JobUID,
			ActionStateID,
			PackageVersionID,
			FailureReason,
			LastUpdate,
			DSVersion
		FROM	#Action AS t
		WHERE NOT EXISTS(	-- Current record doesn't exist
			SELECT * FROM [dbo].[Action]
			WHERE	Action.ActionUID = t.ActionUID
		)
	SET @count = @count + @@ROWCOUNT
	DROP TABLE #Action	-- Drop the temporary table
	COMMIT WORK
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ActionRemoveBatch]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ActionRemoveBatch]
GO

CREATE PROCEDURE [dbo].[ActionRemoveBatch]
AS

	CREATE INDEX [TempActionActionRemoveBatch]
		ON #Action (ActionUID)	

	-- Delete records from Action identified by fields of [TempActionActionRemoveBatch]
	DELETE [dbo].[Action]
	WHERE EXISTS(
			SELECT * FROM #Action AS t
			WHERE	Action.ActionUID = t.ActionUID
		)
	DROP TABLE #Action      -- Drop the temporary table
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ActionRemoveByUID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ActionRemoveByUID]
GO
CREATE PROCEDURE [dbo].[ActionRemoveByUID]
	@ActionUID		binary(16)
AS
	-- Action deletes cascade to:
	--	ActionApplies by FK_ActionApplies_Action
	DELETE	[dbo].[Action]
	WHERE	ActionUID = @ActionUID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ActionRemoveAllByTaskID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ActionRemoveAllByTaskID]
GO
CREATE PROCEDURE [dbo].[ActionRemoveAllByTaskID]
	@TaskID			int
AS
	DELETE	[dbo].[Action]
	WHERE	TaskID = @TaskID
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ActionRemoveAll]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ActionRemoveAll]
GO
CREATE PROCEDURE [dbo].[ActionRemoveAll]
	
AS
	DELETE	[dbo].[Action]
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ActionAppliesGetByID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ActionAppliesGetByID]
GO
CREATE PROCEDURE [dbo].[ActionAppliesGetByID]
	@ActionAppliesID	int
AS
	SELECT	ActionAppliesID,
		ActionUID,
		ComputerID,
		DeviceID,
		MACAddress,
		DNSName,
		IPAddress,
		ActionStateID,
		FailureReason,
		LastUpdate
	FROM	[dbo].[ActionApplies]
	WHERE	ActionAppliesID = @ActionAppliesID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ActionAppliesGetByActionUIDDeviceID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ActionAppliesGetByActionUIDDeviceID]
GO
CREATE PROCEDURE [dbo].[ActionAppliesGetByActionUIDDeviceID]
	@ActionUID		binary(16),
	@DeviceID		int = NULL
AS
	SELECT	ActionAppliesID,
		ActionUID,
		ComputerID,
		DeviceID,
		MACAddress,
		DNSName,
		IPAddress,
		ActionStateID,
		FailureReason,
		LastUpdate
	FROM	[dbo].[ActionApplies]
	WHERE	ActionUID = @ActionUID
	  AND	(DeviceID = @DeviceID OR (DeviceID IS NULL AND @DeviceID IS NULL))
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ActionAppliesGetAllByActionUID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ActionAppliesGetAllByActionUID]
GO
CREATE PROCEDURE [dbo].[ActionAppliesGetAllByActionUID]
	@ActionUID		binary(16)
AS
	SELECT	ActionAppliesID,
		ActionUID,
		ComputerID,
		DeviceID,
		MACAddress,
		DNSName,
		IPAddress,
		ActionStateID,
		FailureReason,
		LastUpdate
	FROM	[dbo].[ActionApplies]
	WHERE	ActionUID = @ActionUID
	ORDER BY DeviceID
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ActionAppliesGetByActionUIDComputerID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ActionAppliesGetByActionUIDComputerID]
GO
CREATE PROCEDURE [dbo].[ActionAppliesGetByActionUIDComputerID]
	@ActionUID		binary(16),
	@ComputerID		int = NULL
AS
	SELECT	ActionAppliesID,
		ActionUID,
		ComputerID,
		DeviceID,
		MACAddress,
		DNSName,
		IPAddress,
		ActionStateID,
		FailureReason,
		LastUpdate
	FROM	[dbo].[ActionApplies]
	WHERE	ActionUID = @ActionUID
	  AND	(ComputerID = @ComputerID OR (ComputerID IS NULL AND @ComputerID IS NULL))
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ActionAppliesGetByActionUIDDNSName]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ActionAppliesGetByActionUIDDNSName]
GO
CREATE PROCEDURE [dbo].[ActionAppliesGetByActionUIDDNSName]
	@ActionUID		binary(16),
	@DNSName		nvarchar(128) = NULL
AS
	SELECT	ActionAppliesID,
		ActionUID,
		ComputerID,
		DeviceID,
		MACAddress,
		DNSName,
		IPAddress,
		ActionStateID,
		FailureReason,
		LastUpdate
	FROM	[dbo].[ActionApplies]
	WHERE	ActionUID = @ActionUID
	  AND	(DNSName = @DNSName OR (DNSName IS NULL AND @DNSName IS NULL))
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ActionAppliesGetByActionUIDIPAddress]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ActionAppliesGetByActionUIDIPAddress]
GO
CREATE PROCEDURE [dbo].[ActionAppliesGetByActionUIDIPAddress]
	@ActionUID		binary(16),
	@IPAddress		varchar(64) = NULL
AS
	SELECT	ActionAppliesID,
		ActionUID,
		ComputerID,
		DeviceID,
		MACAddress,
		DNSName,
		IPAddress,
		ActionStateID,
		FailureReason,
		LastUpdate
	FROM	[dbo].[ActionApplies]
	WHERE	ActionUID = @ActionUID
	  AND	(IPAddress = @IPAddress OR (IPAddress IS NULL AND @IPAddress IS NULL))
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ActionAppliesGetByActionUIDMACAddress]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ActionAppliesGetByActionUIDMACAddress]
GO
CREATE PROCEDURE [dbo].[ActionAppliesGetByActionUIDMACAddress]
	@ActionUID		binary(16),
	@MACAddress		char(18) = NULL
AS
	SELECT	ActionAppliesID,
		ActionUID,
		ComputerID,
		DeviceID,
		MACAddress,
		DNSName,
		IPAddress,
		ActionStateID,
		FailureReason,
		LastUpdate
	FROM	[dbo].[ActionApplies]
	WHERE	ActionUID = @ActionUID
	  AND	(MACAddress = @MACAddress OR (MACAddress IS NULL AND @MACAddress IS NULL))
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ActionAppliesGetByComputerID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ActionAppliesGetByComputerID]
GO
CREATE PROCEDURE [dbo].[ActionAppliesGetByComputerID]
	@ComputerID		int = NULL
AS
	SELECT	ActionAppliesID,
		ActionUID,
		ComputerID,
		DeviceID,
		MACAddress,
		DNSName,
		IPAddress,
		ActionStateID,
		FailureReason,
		LastUpdate
	FROM	[dbo].[ActionApplies]
	WHERE	(ComputerID = @ComputerID OR (ComputerID IS NULL AND @ComputerID IS NULL))
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ActionAppliesGetByDeviceID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ActionAppliesGetByDeviceID]
GO
CREATE PROCEDURE [dbo].[ActionAppliesGetByDeviceID]
	@DeviceID		int = NULL
AS
	SELECT	ActionAppliesID,
		ActionUID,
		ComputerID,
		DeviceID,
		MACAddress,
		DNSName,
		IPAddress,
		ActionStateID,
		FailureReason,
		LastUpdate
	FROM	[dbo].[ActionApplies]
	WHERE	(DeviceID = @DeviceID OR (DeviceID IS NULL AND @DeviceID IS NULL))
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ActionAppliesGetAll]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ActionAppliesGetAll]
GO
CREATE PROCEDURE [dbo].[ActionAppliesGetAll]
AS
	SELECT	ActionAppliesID,
		ActionUID,
		ComputerID,
		DeviceID,
		MACAddress,
		DNSName,
		IPAddress,
		ActionStateID,
		FailureReason,
		LastUpdate
	FROM	[dbo].[ActionApplies]
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ActionAppliesAdd]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ActionAppliesAdd]
GO
CREATE PROCEDURE [dbo].[ActionAppliesAdd]
	@ActionUID		binary(16),
	@ComputerID		int = NULL,
	@DeviceID		int = NULL,
	@MACAddress		char(18) = NULL,
	@DNSName		nvarchar(128) = NULL,
	@IPAddress		varchar(64) = NULL,
	@ActionStateID		int,
	@FailureReason		ntext = NULL,
	@LastUpdate		datetime
AS
	INSERT INTO  dbo.ActionApplies (
		ActionUID,
		ComputerID,
		DeviceID,
		MACAddress,
		DNSName,
		IPAddress,
		ActionStateID,
		FailureReason,
		LastUpdate
	)
	VALUES (
		@ActionUID,
		@ComputerID,
		@DeviceID,
		@MACAddress,
		@DNSName,
		@IPAddress,
		@ActionStateID,
		@FailureReason,
		@LastUpdate
	)
	RETURN SCOPE_IDENTITY()
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ActionAppliesBind]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ActionAppliesBind]
GO
CREATE PROCEDURE [dbo].[ActionAppliesBind]
	@ActionUID		binary(16),
	@ComputerID		int = NULL,
	@DeviceID		int = NULL,
	@MACAddress		char(18) = NULL,
	@DNSName		nvarchar(128) = NULL,
	@IPAddress		varchar(64) = NULL,
	@ActionStateID		int,
	@FailureReason		ntext = NULL,
	@LastUpdate		datetime
AS
	DECLARE	@ID	int

	SELECT	@ID = ActionAppliesID
	FROM	[dbo].[ActionApplies]
	WHERE	ActionUID = @ActionUID
	  AND	(DeviceID = @DeviceID OR (DeviceID IS NULL AND @DeviceID IS NULL))

	IF @ID IS NULL
		EXEC @ID = ActionAppliesAdd @ActionUID,
			@ComputerID,
			@DeviceID,
			@MACAddress,
			@DNSName,
			@IPAddress,
			@ActionStateID,
			@FailureReason,
			@LastUpdate

	RETURN @ID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ActionAppliesSchema]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ActionAppliesSchema]
GO
CREATE PROCEDURE [dbo].[ActionAppliesSchema]
AS
	SELECT
	'IF OBJECT_ID(''tempdb..#ActionApplies'') IS NULL' + CAST(0x0A AS CHAR(1)) +
	'	CREATE TABLE #ActionApplies (' + CAST(0x0A AS CHAR(1)) +
	'		ActionAppliesID		int NULL,' + CAST(0x0A AS CHAR(1)) +
	'		ActionUID		binary(16) NOT NULL,' + CAST(0x0A AS CHAR(1)) +
	'		ComputerID		int NULL,' + CAST(0x0A AS CHAR(1)) +
	'		DeviceID		int NULL,' + CAST(0x0A AS CHAR(1)) +
	'		MACAddress		char(18) COLLATE database_default NULL,' + CAST(0x0A AS CHAR(1)) +
	'		DNSName			nvarchar(128) COLLATE database_default NULL,' + CAST(0x0A AS CHAR(1)) +
	'		IPAddress		varchar(64) COLLATE database_default NULL,' + CAST(0x0A AS CHAR(1)) +
	'		ActionStateID		int NOT NULL,' + CAST(0x0A AS CHAR(1)) +
	'		FailureReason		ntext COLLATE database_default NULL,' + CAST(0x0A AS CHAR(1)) +
	'		LastUpdate		datetime NOT NULL DEFAULT getdate()' + CAST(0x0A AS CHAR(1)) +
	'	)' + CAST(0x0A AS CHAR(1)) +
	'ELSE' + CAST(0x0A AS CHAR(1)) +
	'	DELETE FROM #ActionApplies' + CAST(0x0A AS CHAR(1)) +
	'' AS SQL
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ActionAppliesTempAdd]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ActionAppliesTempAdd]
GO
CREATE PROCEDURE dbo.[ActionAppliesTempAdd]
	@ActionAppliesID	int,
	@ActionUID		binary(16),
	@ComputerID		int = NULL,
	@DeviceID		int = NULL,
	@MACAddress		char(18) = NULL,
	@DNSName		nvarchar(128) = NULL,
	@IPAddress		varchar(64) = NULL,
	@ActionStateID		int,
	@FailureReason		ntext = NULL,
	@LastUpdate		datetime
AS
	INSERT INTO #ActionApplies (
		ActionAppliesID,
		ActionUID,
		ComputerID,
		DeviceID,
		MACAddress,
		DNSName,
		IPAddress,
		ActionStateID,
		FailureReason,
		LastUpdate
	)
	VALUES (
		@ActionAppliesID,
		@ActionUID,
		@ComputerID,
		@DeviceID,
		@MACAddress,
		@DNSName,
		@IPAddress,
		@ActionStateID,
		@FailureReason,
		@LastUpdate
	)
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ActionAppliesAddBatch]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ActionAppliesAddBatch]
GO
CREATE PROCEDURE dbo.[ActionAppliesAddBatch]
AS
	DECLARE @count int
	INSERT dbo.ActionApplies (
		ActionUID,
		ComputerID,
		DeviceID,
		MACAddress,
		DNSName,
		IPAddress,
		ActionStateID,
		FailureReason,
		LastUpdate
	)
		SELECT	ActionUID,
			ComputerID,
			DeviceID,
			MACAddress,
			DNSName,
			IPAddress,
			ActionStateID,
			FailureReason,
			LastUpdate
		FROM #ActionApplies
	SET @count = @@ROWCOUNT
	DROP TABLE #ActionApplies	-- Drop temporary table
	RETURN @count
GO

/*
Add new ActionApplies bound to
	ActionState using ActionStateName
	with ActionUID, ComputerID, DeviceID, MACAddress, DNSName, IPAddress, FailureReason, LastUpdate
*/

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ActionAppliesUpdateByID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ActionAppliesUpdateByID]
GO
CREATE PROCEDURE [dbo].[ActionAppliesUpdateByID]
	@ActionAppliesID	int,
	@ActionUID		binary(16),
	@ComputerID		int = NULL,
	@DeviceID		int = NULL,
	@MACAddress		char(18) = NULL,
	@DNSName		nvarchar(128) = NULL,
	@IPAddress		varchar(64) = NULL,
	@ActionStateID		int,
	@FailureReason		ntext = NULL,
	@LastUpdate		datetime
AS
	DECLARE	@ID	int
	SET @ID = 0

	UPDATE	[dbo].[ActionApplies]
	SET	@ID = ActionAppliesID,
		ActionUID = @ActionUID,
		ComputerID = @ComputerID,
		DeviceID = @DeviceID,
		MACAddress = @MACAddress,
		DNSName = @DNSName,
		IPAddress = @IPAddress,
		ActionStateID = @ActionStateID,
		FailureReason = @FailureReason,
		LastUpdate = @LastUpdate
	WHERE	ActionAppliesID = @ActionAppliesID
	RETURN @ID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ActionAppliesUpdateBatchByID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ActionAppliesUpdateBatchByID]
GO
CREATE PROCEDURE dbo.[ActionAppliesUpdateBatchByID]
AS
	DECLARE @count int

	CREATE INDEX [TempActionAppliesID]
		ON #ActionApplies (ActionAppliesID)

	UPDATE	[dbo].[ActionApplies]
	SET	ActionUID = t.ActionUID,
		ComputerID = t.ComputerID,
		DeviceID = t.DeviceID,
		MACAddress = t.MACAddress,
		DNSName = t.DNSName,
		IPAddress = t.IPAddress,
		ActionStateID = t.ActionStateID,
		FailureReason = t.FailureReason,
		LastUpdate = t.LastUpdate
	FROM	#ActionApplies AS t
	WHERE	ActionApplies.ActionAppliesID = t.ActionAppliesID
	SET @count = @@ROWCOUNT
	DROP TABLE #ActionApplies	-- Drop the temporary table
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ActionAppliesUpdateByActionUIDDeviceID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ActionAppliesUpdateByActionUIDDeviceID]
GO
CREATE PROCEDURE [dbo].[ActionAppliesUpdateByActionUIDDeviceID]
	@ActionUID		binary(16),
	@DeviceID		int = NULL,
	@ComputerID		int = NULL,
	@MACAddress		char(18) = NULL,
	@DNSName		nvarchar(128) = NULL,
	@IPAddress		varchar(64) = NULL,
	@ActionStateID		int,
	@FailureReason		ntext = NULL,
	@LastUpdate		datetime
AS
	DECLARE	@ID	int
	SET @ID = 0

	UPDATE	[dbo].[ActionApplies]
	SET	@ID = ActionAppliesID,
		ComputerID = @ComputerID,
		MACAddress = @MACAddress,
		DNSName = @DNSName,
		IPAddress = @IPAddress,
		ActionStateID = @ActionStateID,
		FailureReason = @FailureReason,
		LastUpdate = @LastUpdate
	WHERE	ActionUID = @ActionUID
	  AND	(DeviceID = @DeviceID OR (DeviceID IS NULL AND @DeviceID IS NULL))
	RETURN @ID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ActionAppliesUpdateBatchByActionUIDDeviceID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ActionAppliesUpdateBatchByActionUIDDeviceID]
GO
CREATE PROCEDURE dbo.[ActionAppliesUpdateBatchByActionUIDDeviceID]
AS
	DECLARE @count int

	CREATE INDEX [TempActionAppliesActionUIDDeviceID]
		ON #ActionApplies (ActionUID, DeviceID)

	UPDATE	[dbo].[ActionApplies]
	SET	ComputerID = t.ComputerID,
		MACAddress = t.MACAddress,
		DNSName = t.DNSName,
		IPAddress = t.IPAddress,
		ActionStateID = t.ActionStateID,
		FailureReason = t.FailureReason,
		LastUpdate = t.LastUpdate
	FROM	#ActionApplies AS t
	WHERE	ActionApplies.ActionUID = t.ActionUID
	  AND	(ActionApplies.DeviceID = t.DeviceID OR (ActionApplies.DeviceID IS NULL AND t.DeviceID IS NULL))
	SET @count = @@ROWCOUNT
	DROP TABLE #ActionApplies	-- Drop the temporary table
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ActionAppliesPutByActionUIDDeviceID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ActionAppliesPutByActionUIDDeviceID]
GO
CREATE PROCEDURE [dbo].[ActionAppliesPutByActionUIDDeviceID]
	@ActionUID		binary(16),
	@DeviceID		int = NULL,
	@ComputerID		int = NULL,
	@MACAddress		char(18) = NULL,
	@DNSName		nvarchar(128) = NULL,
	@IPAddress		varchar(64) = NULL,
	@ActionStateID		int,
	@FailureReason		ntext = NULL,
	@LastUpdate		datetime
AS
	DECLARE @ID	int

	SELECT	@ID = ActionAppliesID
	FROM	ActionApplies
	WHERE	ActionUID = @ActionUID
	  AND	(DeviceID = @DeviceID OR (DeviceID IS NULL AND @DeviceID IS NULL))

	IF @ID IS NULL
		EXEC @ID = ActionAppliesAdd @ActionUID,
			@ComputerID,
			@DeviceID,
			@MACAddress,
			@DNSName,
			@IPAddress,
			@ActionStateID,
			@FailureReason,
			@LastUpdate
	ELSE
		EXEC ActionAppliesUpdateByActionUIDDeviceID @ActionUID,
			@DeviceID,
			@ComputerID,
			@MACAddress,
			@DNSName,
			@IPAddress,
			@ActionStateID,
			@FailureReason,
			@LastUpdate

	RETURN @ID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ActionAppliesPutBatchByActionUIDDeviceID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ActionAppliesPutBatchByActionUIDDeviceID]
GO
CREATE PROCEDURE [dbo].[ActionAppliesPutBatchByActionUIDDeviceID]
AS
	DECLARE @count AS int
	SET @count = 0

	CREATE INDEX [TempActionAppliesActionUIDDeviceID]
		ON #ActionApplies (ActionUID, DeviceID)

	BEGIN TRANSACTION
	UPDATE [dbo].[ActionApplies]
		SET	ComputerID = t.ComputerID,
			MACAddress = t.MACAddress,
			DNSName = t.DNSName,
			IPAddress = t.IPAddress,
			ActionStateID = t.ActionStateID,
			FailureReason = t.FailureReason,
			LastUpdate = t.LastUpdate
		FROM	#ActionApplies AS t
		WHERE	ActionApplies.ActionUID = t.ActionUID
		  AND	(ActionApplies.DeviceID = t.DeviceID OR (ActionApplies.DeviceID IS NULL AND t.DeviceID IS NULL))
	SET @count = @@ROWCOUNT

	INSERT [dbo].[ActionApplies] (
		ActionUID,
		ComputerID,
		DeviceID,
		MACAddress,
		DNSName,
		IPAddress,
		ActionStateID,
		FailureReason,
		LastUpdate
	)
		SELECT	ActionUID,
			ComputerID,
			DeviceID,
			MACAddress,
			DNSName,
			IPAddress,
			ActionStateID,
			FailureReason,
			LastUpdate
		FROM	#ActionApplies AS t
		WHERE NOT EXISTS(	-- Current record doesn't exist
			SELECT * FROM [dbo].[ActionApplies]
			WHERE	ActionApplies.ActionUID = t.ActionUID
			  AND	(ActionApplies.DeviceID = t.DeviceID OR (ActionApplies.DeviceID IS NULL AND t.DeviceID IS NULL))
		)
	SET @count = @count + @@ROWCOUNT
	DROP TABLE #ActionApplies	-- Drop the temporary table
	COMMIT WORK
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ActionAppliesRemoveBatch]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ActionAppliesRemoveBatch]
GO

CREATE PROCEDURE [dbo].[ActionAppliesRemoveBatch]
AS

	CREATE INDEX [TempActionAppliesActionAppliesRemoveBatch]
		ON #ActionApplies (ActionAppliesID)	

	-- Delete records from ActionApplies identified by fields of [TempActionAppliesActionAppliesRemoveBatch]
	DELETE [dbo].[ActionApplies]
	WHERE EXISTS(
			SELECT * FROM #ActionApplies AS t
			WHERE	ActionApplies.ActionAppliesID = t.ActionAppliesID
		)
	DROP TABLE #ActionApplies      -- Drop the temporary table
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ActionAppliesRemoveByID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ActionAppliesRemoveByID]
GO
CREATE PROCEDURE [dbo].[ActionAppliesRemoveByID]
	@ActionAppliesID	int
AS
	DELETE	[dbo].[ActionApplies]
	WHERE	ActionAppliesID = @ActionAppliesID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ActionAppliesRemoveAllByActionUID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ActionAppliesRemoveAllByActionUID]
GO
CREATE PROCEDURE [dbo].[ActionAppliesRemoveAllByActionUID]
	@ActionUID		binary(16)
AS
	DELETE	[dbo].[ActionApplies]
	WHERE	ActionUID = @ActionUID
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ActionAppliesRemoveAll]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ActionAppliesRemoveAll]
GO
CREATE PROCEDURE [dbo].[ActionAppliesRemoveAll]
	
AS
	DELETE	[dbo].[ActionApplies]
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[SoftwareUsagePerWeekGetByID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[SoftwareUsagePerWeekGetByID]
GO
CREATE PROCEDURE [dbo].[SoftwareUsagePerWeekGetByID]
	@SoftwareUsagePerWeekID	int
AS
	SELECT	SoftwareUsagePerWeekID,
		ComputerID,
		UserID,
		SoftwareID,
		SoftwareFileUsageID,
		StartOfWeek,
		Duration,
		ActiveTime,
		Sessions,
		Days
	FROM	[dbo].[SoftwareUsagePerWeek]
	WHERE	SoftwareUsagePerWeekID = @SoftwareUsagePerWeekID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[SoftwareUsagePerWeekGetByComputerIDUserIDSoftwareIDSoftwareFileUsageIDStartOfWeek]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[SoftwareUsagePerWeekGetByComputerIDUserIDSoftwareIDSoftwareFileUsageIDStartOfWeek]
GO
CREATE PROCEDURE [dbo].[SoftwareUsagePerWeekGetByComputerIDUserIDSoftwareIDSoftwareFileUsageIDStartOfWeek]
	@ComputerID		int,
	@UserID			int,
	@SoftwareID		int,
	@SoftwareFileUsageID	int = NULL,
	@StartOfWeek		datetime
AS
	SELECT	SoftwareUsagePerWeekID,
		ComputerID,
		UserID,
		SoftwareID,
		SoftwareFileUsageID,
		StartOfWeek,
		Duration,
		ActiveTime,
		Sessions,
		Days
	FROM	[dbo].[SoftwareUsagePerWeek]
	WHERE	ComputerID = @ComputerID
	  AND	UserID = @UserID
	  AND	SoftwareID = @SoftwareID
	  AND	(SoftwareFileUsageID = @SoftwareFileUsageID OR (SoftwareFileUsageID IS NULL AND @SoftwareFileUsageID IS NULL))
	  AND	StartOfWeek = @StartOfWeek
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[SoftwareUsagePerWeekGetAll]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[SoftwareUsagePerWeekGetAll]
GO
CREATE PROCEDURE [dbo].[SoftwareUsagePerWeekGetAll]
AS
	SELECT	SoftwareUsagePerWeekID,
		ComputerID,
		UserID,
		SoftwareID,
		SoftwareFileUsageID,
		StartOfWeek,
		Duration,
		ActiveTime,
		Sessions,
		Days
	FROM	[dbo].[SoftwareUsagePerWeek]
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[SoftwareUsagePerWeekAdd]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[SoftwareUsagePerWeekAdd]
GO
CREATE PROCEDURE [dbo].[SoftwareUsagePerWeekAdd]
	@ComputerID		int,
	@UserID			int,
	@SoftwareID		int,
	@SoftwareFileUsageID	int = NULL,
	@StartOfWeek		datetime,
	@Duration		int = NULL,
	@ActiveTime		int = NULL,
	@Sessions		int = NULL,
	@Days			int = NULL
AS
	INSERT INTO  dbo.SoftwareUsagePerWeek (
		ComputerID,
		UserID,
		SoftwareID,
		SoftwareFileUsageID,
		StartOfWeek,
		Duration,
		ActiveTime,
		Sessions,
		Days
	)
	VALUES (
		@ComputerID,
		@UserID,
		@SoftwareID,
		@SoftwareFileUsageID,
		@StartOfWeek,
		@Duration,
		@ActiveTime,
		@Sessions,
		@Days
	)
	RETURN SCOPE_IDENTITY()
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[SoftwareUsagePerWeekBind]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[SoftwareUsagePerWeekBind]
GO
CREATE PROCEDURE [dbo].[SoftwareUsagePerWeekBind]
	@ComputerID		int,
	@UserID			int,
	@SoftwareID		int,
	@SoftwareFileUsageID	int = NULL,
	@StartOfWeek		datetime,
	@Duration		int = NULL,
	@ActiveTime		int = NULL,
	@Sessions		int = NULL,
	@Days			int = NULL
AS
	DECLARE	@ID	int

	SELECT	@ID = SoftwareUsagePerWeekID
	FROM	[dbo].[SoftwareUsagePerWeek]
	WHERE	ComputerID = @ComputerID
	  AND	UserID = @UserID
	  AND	SoftwareID = @SoftwareID
	  AND	(SoftwareFileUsageID = @SoftwareFileUsageID OR (SoftwareFileUsageID IS NULL AND @SoftwareFileUsageID IS NULL))
	  AND	StartOfWeek = @StartOfWeek

	IF @ID IS NULL
		EXEC @ID = SoftwareUsagePerWeekAdd @ComputerID,
			@UserID,
			@SoftwareID,
			@SoftwareFileUsageID,
			@StartOfWeek,
			@Duration,
			@ActiveTime,
			@Sessions,
			@Days

	RETURN @ID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[SoftwareUsagePerWeekSchema]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[SoftwareUsagePerWeekSchema]
GO
CREATE PROCEDURE [dbo].[SoftwareUsagePerWeekSchema]
AS
	SELECT
	'IF OBJECT_ID(''tempdb..#SoftwareUsagePerWeek'') IS NULL' + CAST(0x0A AS CHAR(1)) +
	'	CREATE TABLE #SoftwareUsagePerWeek (' + CAST(0x0A AS CHAR(1)) +
	'		SoftwareUsagePerWeekID	int NULL,' + CAST(0x0A AS CHAR(1)) +
	'		ComputerID		int NOT NULL,' + CAST(0x0A AS CHAR(1)) +
	'		UserID			int NOT NULL,' + CAST(0x0A AS CHAR(1)) +
	'		SoftwareID		int NOT NULL,' + CAST(0x0A AS CHAR(1)) +
	'		SoftwareFileUsageID	int NULL,' + CAST(0x0A AS CHAR(1)) +
	'		StartOfWeek		datetime NOT NULL,' + CAST(0x0A AS CHAR(1)) +
	'		Duration		int NULL,' + CAST(0x0A AS CHAR(1)) +
	'		ActiveTime		int NULL,' + CAST(0x0A AS CHAR(1)) +
	'		Sessions		int NULL,' + CAST(0x0A AS CHAR(1)) +
	'		Days			int NULL' + CAST(0x0A AS CHAR(1)) +
	'	)' + CAST(0x0A AS CHAR(1)) +
	'ELSE' + CAST(0x0A AS CHAR(1)) +
	'	DELETE FROM #SoftwareUsagePerWeek' + CAST(0x0A AS CHAR(1)) +
	'' AS SQL
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[SoftwareUsagePerWeekTempAdd]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[SoftwareUsagePerWeekTempAdd]
GO
CREATE PROCEDURE dbo.[SoftwareUsagePerWeekTempAdd]
	@SoftwareUsagePerWeekID	int,
	@ComputerID		int,
	@UserID			int,
	@SoftwareID		int,
	@SoftwareFileUsageID	int = NULL,
	@StartOfWeek		datetime,
	@Duration		int = NULL,
	@ActiveTime		int = NULL,
	@Sessions		int = NULL,
	@Days			int = NULL
AS
	INSERT INTO #SoftwareUsagePerWeek (
		SoftwareUsagePerWeekID,
		ComputerID,
		UserID,
		SoftwareID,
		SoftwareFileUsageID,
		StartOfWeek,
		Duration,
		ActiveTime,
		Sessions,
		Days
	)
	VALUES (
		@SoftwareUsagePerWeekID,
		@ComputerID,
		@UserID,
		@SoftwareID,
		@SoftwareFileUsageID,
		@StartOfWeek,
		@Duration,
		@ActiveTime,
		@Sessions,
		@Days
	)
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[SoftwareUsagePerWeekAddBatch]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[SoftwareUsagePerWeekAddBatch]
GO
CREATE PROCEDURE dbo.[SoftwareUsagePerWeekAddBatch]
AS
	DECLARE @count int
	INSERT dbo.SoftwareUsagePerWeek (
		ComputerID,
		UserID,
		SoftwareID,
		SoftwareFileUsageID,
		StartOfWeek,
		Duration,
		ActiveTime,
		Sessions,
		Days
	)
		SELECT	ComputerID,
			UserID,
			SoftwareID,
			SoftwareFileUsageID,
			StartOfWeek,
			Duration,
			ActiveTime,
			Sessions,
			Days
		FROM #SoftwareUsagePerWeek
	SET @count = @@ROWCOUNT
	DROP TABLE #SoftwareUsagePerWeek	-- Drop temporary table
	RETURN @count
GO

/*
Add new SoftwareUsagePerWeek bound to
	SoftwareVersion using SoftwareName, Version
	User using UserOUID, UserCN
	SoftwareFileUsage using ComputerID, UserID, SoftwareFileNameID, Version, CompanyName, Description, ProductName, ProductVersion
	with ComputerID, StartOfWeek, Duration, ActiveTime, Sessions, Days
*/

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[SoftwareUsagePerWeekUpdateByID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[SoftwareUsagePerWeekUpdateByID]
GO
CREATE PROCEDURE [dbo].[SoftwareUsagePerWeekUpdateByID]
	@SoftwareUsagePerWeekID	int,
	@ComputerID		int,
	@UserID			int,
	@SoftwareID		int,
	@SoftwareFileUsageID	int = NULL,
	@StartOfWeek		datetime,
	@Duration		int = NULL,
	@ActiveTime		int = NULL,
	@Sessions		int = NULL,
	@Days			int = NULL
AS
	DECLARE	@ID	int
	SET @ID = 0

	UPDATE	[dbo].[SoftwareUsagePerWeek]
	SET	@ID = SoftwareUsagePerWeekID,
		ComputerID = @ComputerID,
		UserID = @UserID,
		SoftwareID = @SoftwareID,
		SoftwareFileUsageID = @SoftwareFileUsageID,
		StartOfWeek = @StartOfWeek,
		Duration = @Duration,
		ActiveTime = @ActiveTime,
		Sessions = @Sessions,
		Days = @Days
	WHERE	SoftwareUsagePerWeekID = @SoftwareUsagePerWeekID
	RETURN @ID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[SoftwareUsagePerWeekUpdateBatchByID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[SoftwareUsagePerWeekUpdateBatchByID]
GO
CREATE PROCEDURE dbo.[SoftwareUsagePerWeekUpdateBatchByID]
AS
	DECLARE @count int

	CREATE INDEX [TempSoftwareUsagePerWeekID]
		ON #SoftwareUsagePerWeek (SoftwareUsagePerWeekID)

	UPDATE	[dbo].[SoftwareUsagePerWeek]
	SET	ComputerID = t.ComputerID,
		UserID = t.UserID,
		SoftwareID = t.SoftwareID,
		SoftwareFileUsageID = t.SoftwareFileUsageID,
		StartOfWeek = t.StartOfWeek,
		Duration = t.Duration,
		ActiveTime = t.ActiveTime,
		Sessions = t.Sessions,
		Days = t.Days
	FROM	#SoftwareUsagePerWeek AS t
	WHERE	SoftwareUsagePerWeek.SoftwareUsagePerWeekID = t.SoftwareUsagePerWeekID
	SET @count = @@ROWCOUNT
	DROP TABLE #SoftwareUsagePerWeek	-- Drop the temporary table
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[SoftwareUsagePerWeekUpdateByComputerIDUserIDSoftwareIDSoftwareFileUsageIDStartOfWeek]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[SoftwareUsagePerWeekUpdateByComputerIDUserIDSoftwareIDSoftwareFileUsageIDStartOfWeek]
GO
CREATE PROCEDURE [dbo].[SoftwareUsagePerWeekUpdateByComputerIDUserIDSoftwareIDSoftwareFileUsageIDStartOfWeek]
	@ComputerID		int,
	@UserID			int,
	@SoftwareID		int,
	@SoftwareFileUsageID	int = NULL,
	@StartOfWeek		datetime,
	@Duration		int = NULL,
	@ActiveTime		int = NULL,
	@Sessions		int = NULL,
	@Days			int = NULL
AS
	DECLARE	@ID	int
	SET @ID = 0

	UPDATE	[dbo].[SoftwareUsagePerWeek]
	SET	@ID = SoftwareUsagePerWeekID,
		Duration = @Duration,
		ActiveTime = @ActiveTime,
		Sessions = @Sessions,
		Days = @Days
	WHERE	ComputerID = @ComputerID
	  AND	UserID = @UserID
	  AND	SoftwareID = @SoftwareID
	  AND	(SoftwareFileUsageID = @SoftwareFileUsageID OR (SoftwareFileUsageID IS NULL AND @SoftwareFileUsageID IS NULL))
	  AND	StartOfWeek = @StartOfWeek
	RETURN @ID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[SoftwareUsagePerWeekUpdateBatchByComputerIDUserIDSoftwareIDSoftwareFileUsageIDStartOfWeek]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[SoftwareUsagePerWeekUpdateBatchByComputerIDUserIDSoftwareIDSoftwareFileUsageIDStartOfWeek]
GO
CREATE PROCEDURE dbo.[SoftwareUsagePerWeekUpdateBatchByComputerIDUserIDSoftwareIDSoftwareFileUsageIDStartOfWeek]
AS
	DECLARE @count int

	CREATE INDEX [TempSoftwareUsagePerWeekComputerIDUserIDSoftwareIDSoftwareFileUsageIDStartOfWeek]
		ON #SoftwareUsagePerWeek (ComputerID, UserID, SoftwareID, SoftwareFileUsageID, StartOfWeek)

	UPDATE	[dbo].[SoftwareUsagePerWeek]
	SET	Duration = t.Duration,
		ActiveTime = t.ActiveTime,
		Sessions = t.Sessions,
		Days = t.Days
	FROM	#SoftwareUsagePerWeek AS t
	WHERE	SoftwareUsagePerWeek.ComputerID = t.ComputerID
	  AND	SoftwareUsagePerWeek.UserID = t.UserID
	  AND	SoftwareUsagePerWeek.SoftwareID = t.SoftwareID
	  AND	(SoftwareUsagePerWeek.SoftwareFileUsageID = t.SoftwareFileUsageID OR (SoftwareUsagePerWeek.SoftwareFileUsageID IS NULL AND t.SoftwareFileUsageID IS NULL))
	  AND	SoftwareUsagePerWeek.StartOfWeek = t.StartOfWeek
	SET @count = @@ROWCOUNT
	DROP TABLE #SoftwareUsagePerWeek	-- Drop the temporary table
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[SoftwareUsagePerWeekPutByComputerIDUserIDSoftwareIDSoftwareFileUsageIDStartOfWeek]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[SoftwareUsagePerWeekPutByComputerIDUserIDSoftwareIDSoftwareFileUsageIDStartOfWeek]
GO
CREATE PROCEDURE [dbo].[SoftwareUsagePerWeekPutByComputerIDUserIDSoftwareIDSoftwareFileUsageIDStartOfWeek]
	@ComputerID		int,
	@UserID			int,
	@SoftwareID		int,
	@SoftwareFileUsageID	int = NULL,
	@StartOfWeek		datetime,
	@Duration		int = NULL,
	@ActiveTime		int = NULL,
	@Sessions		int = NULL,
	@Days			int = NULL
AS
	DECLARE @ID	int

	SELECT	@ID = SoftwareUsagePerWeekID
	FROM	SoftwareUsagePerWeek
	WHERE	ComputerID = @ComputerID
	  AND	UserID = @UserID
	  AND	SoftwareID = @SoftwareID
	  AND	(SoftwareFileUsageID = @SoftwareFileUsageID OR (SoftwareFileUsageID IS NULL AND @SoftwareFileUsageID IS NULL))
	  AND	StartOfWeek = @StartOfWeek

	IF @ID IS NULL
		EXEC @ID = SoftwareUsagePerWeekAdd @ComputerID,
			@UserID,
			@SoftwareID,
			@SoftwareFileUsageID,
			@StartOfWeek,
			@Duration,
			@ActiveTime,
			@Sessions,
			@Days
	ELSE
		EXEC SoftwareUsagePerWeekUpdateByComputerIDUserIDSoftwareIDSoftwareFileUsageIDStartOfWeek @ComputerID,
			@UserID,
			@SoftwareID,
			@SoftwareFileUsageID,
			@StartOfWeek,
			@Duration,
			@ActiveTime,
			@Sessions,
			@Days

	RETURN @ID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[SoftwareUsagePerWeekPutBatchByComputerIDUserIDSoftwareIDSoftwareFileUsageIDStartOfWeek]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[SoftwareUsagePerWeekPutBatchByComputerIDUserIDSoftwareIDSoftwareFileUsageIDStartOfWeek]
GO
CREATE PROCEDURE [dbo].[SoftwareUsagePerWeekPutBatchByComputerIDUserIDSoftwareIDSoftwareFileUsageIDStartOfWeek]
AS
	DECLARE @count AS int
	SET @count = 0

	CREATE INDEX [TempSoftwareUsagePerWeekComputerIDUserIDSoftwareIDSoftwareFileUsageIDStartOfWeek]
		ON #SoftwareUsagePerWeek (ComputerID, UserID, SoftwareID, SoftwareFileUsageID, StartOfWeek)

	BEGIN TRANSACTION
	UPDATE [dbo].[SoftwareUsagePerWeek]
		SET	Duration = t.Duration,
			ActiveTime = t.ActiveTime,
			Sessions = t.Sessions,
			Days = t.Days
		FROM	#SoftwareUsagePerWeek AS t
		WHERE	SoftwareUsagePerWeek.ComputerID = t.ComputerID
		  AND	SoftwareUsagePerWeek.UserID = t.UserID
		  AND	SoftwareUsagePerWeek.SoftwareID = t.SoftwareID
		  AND	(SoftwareUsagePerWeek.SoftwareFileUsageID = t.SoftwareFileUsageID OR (SoftwareUsagePerWeek.SoftwareFileUsageID IS NULL AND t.SoftwareFileUsageID IS NULL))
		  AND	SoftwareUsagePerWeek.StartOfWeek = t.StartOfWeek
	SET @count = @@ROWCOUNT

	INSERT [dbo].[SoftwareUsagePerWeek] (
		ComputerID,
		UserID,
		SoftwareID,
		SoftwareFileUsageID,
		StartOfWeek,
		Duration,
		ActiveTime,
		Sessions,
		Days
	)
		SELECT	ComputerID,
			UserID,
			SoftwareID,
			SoftwareFileUsageID,
			StartOfWeek,
			Duration,
			ActiveTime,
			Sessions,
			Days
		FROM	#SoftwareUsagePerWeek AS t
		WHERE NOT EXISTS(	-- Current record doesn't exist
			SELECT * FROM [dbo].[SoftwareUsagePerWeek]
			WHERE	SoftwareUsagePerWeek.ComputerID = t.ComputerID
			  AND	SoftwareUsagePerWeek.UserID = t.UserID
			  AND	SoftwareUsagePerWeek.SoftwareID = t.SoftwareID
			  AND	(SoftwareUsagePerWeek.SoftwareFileUsageID = t.SoftwareFileUsageID OR (SoftwareUsagePerWeek.SoftwareFileUsageID IS NULL AND t.SoftwareFileUsageID IS NULL))
			  AND	SoftwareUsagePerWeek.StartOfWeek = t.StartOfWeek
		)
	SET @count = @count + @@ROWCOUNT
	DROP TABLE #SoftwareUsagePerWeek	-- Drop the temporary table
	COMMIT WORK
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[SoftwareUsagePerWeekRemoveBatch]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[SoftwareUsagePerWeekRemoveBatch]
GO

CREATE PROCEDURE [dbo].[SoftwareUsagePerWeekRemoveBatch]
AS

	CREATE INDEX [TempSoftwareUsagePerWeekSoftwareUsagePerWeekRemoveBatch]
		ON #SoftwareUsagePerWeek (SoftwareUsagePerWeekID)	

	-- Delete records from SoftwareUsagePerWeek identified by fields of [TempSoftwareUsagePerWeekSoftwareUsagePerWeekRemoveBatch]
	DELETE [dbo].[SoftwareUsagePerWeek]
	WHERE EXISTS(
			SELECT * FROM #SoftwareUsagePerWeek AS t
			WHERE	SoftwareUsagePerWeek.SoftwareUsagePerWeekID = t.SoftwareUsagePerWeekID
		)
	DROP TABLE #SoftwareUsagePerWeek      -- Drop the temporary table
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[SoftwareUsagePerWeekRemoveByID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[SoftwareUsagePerWeekRemoveByID]
GO
CREATE PROCEDURE [dbo].[SoftwareUsagePerWeekRemoveByID]
	@SoftwareUsagePerWeekID	int
AS
	DELETE	[dbo].[SoftwareUsagePerWeek]
	WHERE	SoftwareUsagePerWeekID = @SoftwareUsagePerWeekID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[SoftwareUsagePerWeekRemoveAll]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[SoftwareUsagePerWeekRemoveAll]
GO
CREATE PROCEDURE [dbo].[SoftwareUsagePerWeekRemoveAll]
	
AS
	DELETE	[dbo].[SoftwareUsagePerWeek]
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ComputerUsageGetByComputerIDUserID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ComputerUsageGetByComputerIDUserID]
GO
CREATE PROCEDURE [dbo].[ComputerUsageGetByComputerIDUserID]
	@ComputerID		int,
	@UserID			int
AS
	SELECT	ComputerID,
		UserID,
		LastReported
	FROM	[dbo].[ComputerUsage]
	WHERE	ComputerID = @ComputerID
	  AND	UserID = @UserID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ComputerUsageGetAll]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ComputerUsageGetAll]
GO
CREATE PROCEDURE [dbo].[ComputerUsageGetAll]
AS
	SELECT	ComputerID,
		UserID,
		LastReported
	FROM	[dbo].[ComputerUsage]
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ComputerUsageAdd]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ComputerUsageAdd]
GO
CREATE PROCEDURE [dbo].[ComputerUsageAdd]
	@ComputerID		int,
	@UserID			int,
	@LastReported		datetime = NULL
AS
	INSERT INTO  dbo.ComputerUsage (
		ComputerID,
		UserID,
		LastReported
	)
	VALUES (
		@ComputerID,
		@UserID,
		@LastReported
	)
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ComputerUsageSchema]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ComputerUsageSchema]
GO
CREATE PROCEDURE [dbo].[ComputerUsageSchema]
AS
	SELECT
	'IF OBJECT_ID(''tempdb..#ComputerUsage'') IS NULL' + CAST(0x0A AS CHAR(1)) +
	'	CREATE TABLE #ComputerUsage (' + CAST(0x0A AS CHAR(1)) +
	'		ComputerID		int NOT NULL,' + CAST(0x0A AS CHAR(1)) +
	'		UserID			int NOT NULL,' + CAST(0x0A AS CHAR(1)) +
	'		LastReported		datetime NULL' + CAST(0x0A AS CHAR(1)) +
	'	)' + CAST(0x0A AS CHAR(1)) +
	'ELSE' + CAST(0x0A AS CHAR(1)) +
	'	DELETE FROM #ComputerUsage' + CAST(0x0A AS CHAR(1)) +
	'' AS SQL
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ComputerUsageTempAdd]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ComputerUsageTempAdd]
GO
CREATE PROCEDURE dbo.[ComputerUsageTempAdd]
	@ComputerID		int,
	@UserID			int,
	@LastReported		datetime = NULL
AS
	INSERT INTO #ComputerUsage (
		ComputerID,
		UserID,
		LastReported
	)
	VALUES (
		@ComputerID,
		@UserID,
		@LastReported
	)
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ComputerUsageAddBatch]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ComputerUsageAddBatch]
GO
CREATE PROCEDURE dbo.[ComputerUsageAddBatch]
AS
	DECLARE @count int
	INSERT dbo.ComputerUsage (
		ComputerID,
		UserID,
		LastReported
	)
		SELECT	ComputerID,
			UserID,
			LastReported
		FROM #ComputerUsage
	SET @count = @@ROWCOUNT
	DROP TABLE #ComputerUsage	-- Drop temporary table
	RETURN @count
GO

/*
Add new ComputerUsage bound to
	User using UserOUID, UserCN
	with ComputerID, LastReported
*/

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ComputerUsageUpdateByComputerIDUserID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ComputerUsageUpdateByComputerIDUserID]
GO
CREATE PROCEDURE [dbo].[ComputerUsageUpdateByComputerIDUserID]
	@ComputerID		int,
	@UserID			int,
	@LastReported		datetime = NULL
AS
	UPDATE	[dbo].[ComputerUsage]
	SET	LastReported = @LastReported
	WHERE	ComputerID = @ComputerID
	  AND	UserID = @UserID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ComputerUsageUpdateBatchByComputerIDUserID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ComputerUsageUpdateBatchByComputerIDUserID]
GO
CREATE PROCEDURE dbo.[ComputerUsageUpdateBatchByComputerIDUserID]
AS
	DECLARE @count int

	CREATE INDEX [TempComputerUsageComputerIDUserID]
		ON #ComputerUsage (ComputerID, UserID)

	UPDATE	[dbo].[ComputerUsage]
	SET	LastReported = t.LastReported
	FROM	#ComputerUsage AS t
	WHERE	ComputerUsage.ComputerID = t.ComputerID
	  AND	ComputerUsage.UserID = t.UserID
	SET @count = @@ROWCOUNT
	DROP TABLE #ComputerUsage	-- Drop the temporary table
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ComputerUsagePutByComputerIDUserID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ComputerUsagePutByComputerIDUserID]
GO
CREATE PROCEDURE [dbo].[ComputerUsagePutByComputerIDUserID]
	@ComputerID		int,
	@UserID			int,
	@LastReported		datetime = NULL
AS
	IF NOT EXISTS(
		SELECT	1
		FROM	dbo.ComputerUsage
		WHERE	ComputerID = @ComputerID
		  AND	UserID = @UserID
	)
		EXEC ComputerUsageAdd @ComputerID,
			@UserID,
			@LastReported
	ELSE
		EXEC ComputerUsageUpdateByComputerIDUserID @ComputerID,
			@UserID,
			@LastReported
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ComputerUsagePutBatchByComputerIDUserID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ComputerUsagePutBatchByComputerIDUserID]
GO
CREATE PROCEDURE [dbo].[ComputerUsagePutBatchByComputerIDUserID]
AS
	DECLARE @count AS int
	SET @count = 0

	CREATE INDEX [TempComputerUsageComputerIDUserID]
		ON #ComputerUsage (ComputerID, UserID)

	BEGIN TRANSACTION
	UPDATE [dbo].[ComputerUsage]
		SET	LastReported = t.LastReported
		FROM	#ComputerUsage AS t
		WHERE	ComputerUsage.ComputerID = t.ComputerID
		  AND	ComputerUsage.UserID = t.UserID
	SET @count = @@ROWCOUNT

	INSERT [dbo].[ComputerUsage] (
		ComputerID,
		UserID,
		LastReported
	)
		SELECT	ComputerID,
			UserID,
			LastReported
		FROM	#ComputerUsage AS t
		WHERE NOT EXISTS(	-- Current record doesn't exist
			SELECT * FROM [dbo].[ComputerUsage]
			WHERE	ComputerUsage.ComputerID = t.ComputerID
			  AND	ComputerUsage.UserID = t.UserID
		)
	SET @count = @count + @@ROWCOUNT
	DROP TABLE #ComputerUsage	-- Drop the temporary table
	COMMIT WORK
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ComputerUsageRemoveBatch]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ComputerUsageRemoveBatch]
GO

CREATE PROCEDURE [dbo].[ComputerUsageRemoveBatch]
AS

	CREATE INDEX [TempComputerUsageComputerUsageRemoveBatch]
		ON #ComputerUsage (ComputerID, UserID)	

	-- Delete records from ComputerUsage identified by fields of [TempComputerUsageComputerUsageRemoveBatch]
	DELETE [dbo].[ComputerUsage]
	WHERE EXISTS(
			SELECT * FROM #ComputerUsage AS t
			WHERE	ComputerUsage.ComputerID = t.ComputerID
			  AND	ComputerUsage.UserID = t.UserID
		)
	DROP TABLE #ComputerUsage      -- Drop the temporary table
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ComputerUsageRemoveByComputerIDUserID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ComputerUsageRemoveByComputerIDUserID]
GO
CREATE PROCEDURE [dbo].[ComputerUsageRemoveByComputerIDUserID]
	@ComputerID		int,
	@UserID			int
AS
	DELETE	[dbo].[ComputerUsage]
	WHERE	ComputerID = @ComputerID
	  AND	UserID = @UserID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ComputerUsageRemoveAll]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ComputerUsageRemoveAll]
GO
CREATE PROCEDURE [dbo].[ComputerUsageRemoveAll]
	
AS
	DELETE	[dbo].[ComputerUsage]
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[SoftwareFileUsageGetByComputerIDUserIDSoftwareFileNameIDVersionCompanyNameDescriptionProductNameProductVersion]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[SoftwareFileUsageGetByComputerIDUserIDSoftwareFileNameIDVersionCompanyNameDescriptionProductNameProductVersion]
GO
CREATE PROCEDURE [dbo].[SoftwareFileUsageGetByComputerIDUserIDSoftwareFileNameIDVersionCompanyNameDescriptionProductNameProductVersion]
	@ComputerID		int,
	@UserID			int,
	@SoftwareFileNameID	int,
	@Version		nvarchar(32),
	@CompanyName		nvarchar(50),
	@Description		nvarchar(1024),
	@ProductName		nvarchar(50),
	@ProductVersion		nvarchar(32)
AS
	SELECT	SoftwareFileUsageID,
		ComputerID,
		UserID,
		Version,
		SoftwareFileNameID,
		LongName,
		CompanyName,
		Description,
		ProductName,
		ProductVersion
	FROM	[dbo].[SoftwareFileUsage]
	WHERE	ComputerID = @ComputerID
	  AND	UserID = @UserID
	  AND	SoftwareFileNameID = @SoftwareFileNameID
	  AND	Version = @Version
	  AND	CompanyName = @CompanyName
	  AND	Description = @Description
	  AND	ProductName = @ProductName
	  AND	ProductVersion = @ProductVersion
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[SoftwareFileUsageGetByID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[SoftwareFileUsageGetByID]
GO
CREATE PROCEDURE [dbo].[SoftwareFileUsageGetByID]
	@SoftwareFileUsageID	int
AS
	SELECT	SoftwareFileUsageID,
		ComputerID,
		UserID,
		Version,
		SoftwareFileNameID,
		LongName,
		CompanyName,
		Description,
		ProductName,
		ProductVersion
	FROM	[dbo].[SoftwareFileUsage]
	WHERE	SoftwareFileUsageID = @SoftwareFileUsageID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[SoftwareFileUsageGetAll]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[SoftwareFileUsageGetAll]
GO
CREATE PROCEDURE [dbo].[SoftwareFileUsageGetAll]
AS
	SELECT	SoftwareFileUsageID,
		ComputerID,
		UserID,
		Version,
		SoftwareFileNameID,
		LongName,
		CompanyName,
		Description,
		ProductName,
		ProductVersion
	FROM	[dbo].[SoftwareFileUsage]
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[SoftwareFileUsageAdd]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[SoftwareFileUsageAdd]
GO
CREATE PROCEDURE [dbo].[SoftwareFileUsageAdd]
	@ComputerID		int,
	@UserID			int,
	@Version		nvarchar(32),
	@SoftwareFileNameID	int,
	@LongName		nvarchar(4000) = NULL,
	@CompanyName		nvarchar(50),
	@Description		nvarchar(1024),
	@ProductName		nvarchar(50),
	@ProductVersion		nvarchar(32)
AS
	INSERT INTO  dbo.SoftwareFileUsage (
		ComputerID,
		UserID,
		Version,
		SoftwareFileNameID,
		LongName,
		CompanyName,
		Description,
		ProductName,
		ProductVersion
	)
	VALUES (
		@ComputerID,
		@UserID,
		@Version,
		@SoftwareFileNameID,
		@LongName,
		@CompanyName,
		@Description,
		@ProductName,
		@ProductVersion
	)
	RETURN SCOPE_IDENTITY()
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[SoftwareFileUsageBind]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[SoftwareFileUsageBind]
GO
CREATE PROCEDURE [dbo].[SoftwareFileUsageBind]
	@ComputerID		int,
	@UserID			int,
	@Version		nvarchar(32),
	@SoftwareFileNameID	int,
	@LongName		nvarchar(4000) = NULL,
	@CompanyName		nvarchar(50),
	@Description		nvarchar(1024),
	@ProductName		nvarchar(50),
	@ProductVersion		nvarchar(32)
AS
	DECLARE	@ID	int

	SELECT	@ID = SoftwareFileUsageID
	FROM	[dbo].[SoftwareFileUsage]
	WHERE	ComputerID = @ComputerID
	  AND	UserID = @UserID
	  AND	SoftwareFileNameID = @SoftwareFileNameID
	  AND	Version = @Version
	  AND	CompanyName = @CompanyName
	  AND	Description = @Description
	  AND	ProductName = @ProductName
	  AND	ProductVersion = @ProductVersion

	IF @ID IS NULL
		EXEC @ID = SoftwareFileUsageAdd @ComputerID,
			@UserID,
			@Version,
			@SoftwareFileNameID,
			@LongName,
			@CompanyName,
			@Description,
			@ProductName,
			@ProductVersion

	RETURN @ID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[SoftwareFileUsageSchema]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[SoftwareFileUsageSchema]
GO
CREATE PROCEDURE [dbo].[SoftwareFileUsageSchema]
AS
	SELECT
	'IF OBJECT_ID(''tempdb..#SoftwareFileUsage'') IS NULL' + CAST(0x0A AS CHAR(1)) +
	'	CREATE TABLE #SoftwareFileUsage (' + CAST(0x0A AS CHAR(1)) +
	'		SoftwareFileUsageID	int NULL,' + CAST(0x0A AS CHAR(1)) +
	'		ComputerID		int NOT NULL,' + CAST(0x0A AS CHAR(1)) +
	'		UserID			int NOT NULL,' + CAST(0x0A AS CHAR(1)) +
	'		Version			nvarchar(32) COLLATE database_default NOT NULL,' + CAST(0x0A AS CHAR(1)) +
	'		SoftwareFileNameID	int NOT NULL,' + CAST(0x0A AS CHAR(1)) +
	'		LongName		nvarchar(4000) COLLATE database_default NULL,' + CAST(0x0A AS CHAR(1)) +
	'		CompanyName		nvarchar(50) COLLATE database_default NOT NULL,' + CAST(0x0A AS CHAR(1)) +
	'		Description		nvarchar(1024) COLLATE database_default NOT NULL,' + CAST(0x0A AS CHAR(1)) +
	'		ProductName		nvarchar(50) COLLATE database_default NOT NULL,' + CAST(0x0A AS CHAR(1)) +
	'		ProductVersion		nvarchar(32) COLLATE database_default NOT NULL' + CAST(0x0A AS CHAR(1)) +
	'	)' + CAST(0x0A AS CHAR(1)) +
	'ELSE' + CAST(0x0A AS CHAR(1)) +
	'	DELETE FROM #SoftwareFileUsage' + CAST(0x0A AS CHAR(1)) +
	'' AS SQL
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[SoftwareFileUsageTempAdd]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[SoftwareFileUsageTempAdd]
GO
CREATE PROCEDURE dbo.[SoftwareFileUsageTempAdd]
	@SoftwareFileUsageID	int,
	@ComputerID		int,
	@UserID			int,
	@Version		nvarchar(32),
	@SoftwareFileNameID	int,
	@LongName		nvarchar(4000) = NULL,
	@CompanyName		nvarchar(50),
	@Description		nvarchar(1024),
	@ProductName		nvarchar(50),
	@ProductVersion		nvarchar(32)
AS
	INSERT INTO #SoftwareFileUsage (
		SoftwareFileUsageID,
		ComputerID,
		UserID,
		Version,
		SoftwareFileNameID,
		LongName,
		CompanyName,
		Description,
		ProductName,
		ProductVersion
	)
	VALUES (
		@SoftwareFileUsageID,
		@ComputerID,
		@UserID,
		@Version,
		@SoftwareFileNameID,
		@LongName,
		@CompanyName,
		@Description,
		@ProductName,
		@ProductVersion
	)
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[SoftwareFileUsageAddBatch]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[SoftwareFileUsageAddBatch]
GO
CREATE PROCEDURE dbo.[SoftwareFileUsageAddBatch]
AS
	DECLARE @count int
	INSERT dbo.SoftwareFileUsage (
		ComputerID,
		UserID,
		Version,
		SoftwareFileNameID,
		LongName,
		CompanyName,
		Description,
		ProductName,
		ProductVersion
	)
		SELECT	ComputerID,
			UserID,
			Version,
			SoftwareFileNameID,
			LongName,
			CompanyName,
			Description,
			ProductName,
			ProductVersion
		FROM #SoftwareFileUsage
	SET @count = @@ROWCOUNT
	DROP TABLE #SoftwareFileUsage	-- Drop temporary table
	RETURN @count
GO

/*
Add new SoftwareFileUsage bound to
	SoftwareFileName using Name
	with ComputerID, UserID, Version, LongName, CompanyName, Description, ProductName, ProductVersion
*/

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[SoftwareFileUsageUpdateByID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[SoftwareFileUsageUpdateByID]
GO
CREATE PROCEDURE [dbo].[SoftwareFileUsageUpdateByID]
	@SoftwareFileUsageID	int,
	@ComputerID		int,
	@UserID			int,
	@Version		nvarchar(32),
	@SoftwareFileNameID	int,
	@LongName		nvarchar(4000) = NULL,
	@CompanyName		nvarchar(50),
	@Description		nvarchar(1024),
	@ProductName		nvarchar(50),
	@ProductVersion		nvarchar(32)
AS
	DECLARE	@ID	int
	SET @ID = 0

	UPDATE	[dbo].[SoftwareFileUsage]
	SET	@ID = SoftwareFileUsageID,
		ComputerID = @ComputerID,
		UserID = @UserID,
		Version = @Version,
		SoftwareFileNameID = @SoftwareFileNameID,
		LongName = @LongName,
		CompanyName = @CompanyName,
		Description = @Description,
		ProductName = @ProductName,
		ProductVersion = @ProductVersion
	WHERE	SoftwareFileUsageID = @SoftwareFileUsageID
	RETURN @ID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[SoftwareFileUsageUpdateBatchByID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[SoftwareFileUsageUpdateBatchByID]
GO
CREATE PROCEDURE dbo.[SoftwareFileUsageUpdateBatchByID]
AS
	DECLARE @count int

	CREATE INDEX [TempSoftwareFileUsageID]
		ON #SoftwareFileUsage (SoftwareFileUsageID)

	UPDATE	[dbo].[SoftwareFileUsage]
	SET	ComputerID = t.ComputerID,
		UserID = t.UserID,
		Version = t.Version,
		SoftwareFileNameID = t.SoftwareFileNameID,
		LongName = t.LongName,
		CompanyName = t.CompanyName,
		Description = t.Description,
		ProductName = t.ProductName,
		ProductVersion = t.ProductVersion
	FROM	#SoftwareFileUsage AS t
	WHERE	SoftwareFileUsage.SoftwareFileUsageID = t.SoftwareFileUsageID
	SET @count = @@ROWCOUNT
	DROP TABLE #SoftwareFileUsage	-- Drop the temporary table
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[SoftwareFileUsageUpdateByComputerIDUserIDSoftwareFileNameIDVersionCompanyNameDescriptionProductNameProductVersion]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[SoftwareFileUsageUpdateByComputerIDUserIDSoftwareFileNameIDVersionCompanyNameDescriptionProductNameProductVersion]
GO
CREATE PROCEDURE [dbo].[SoftwareFileUsageUpdateByComputerIDUserIDSoftwareFileNameIDVersionCompanyNameDescriptionProductNameProductVersion]
	@ComputerID		int,
	@UserID			int,
	@SoftwareFileNameID	int,
	@Version		nvarchar(32),
	@CompanyName		nvarchar(50),
	@Description		nvarchar(1024),
	@ProductName		nvarchar(50),
	@ProductVersion		nvarchar(32),
	@LongName		nvarchar(4000) = NULL
AS
	DECLARE	@ID	int
	SET @ID = 0

	UPDATE	[dbo].[SoftwareFileUsage]
	SET	@ID = SoftwareFileUsageID,
		LongName = @LongName
	WHERE	ComputerID = @ComputerID
	  AND	UserID = @UserID
	  AND	SoftwareFileNameID = @SoftwareFileNameID
	  AND	Version = @Version
	  AND	CompanyName = @CompanyName
	  AND	Description = @Description
	  AND	ProductName = @ProductName
	  AND	ProductVersion = @ProductVersion
	RETURN @ID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[SoftwareFileUsageUpdateBatchByComputerIDUserIDSoftwareFileNameIDVersionCompanyNameDescriptionProductNameProductVersion]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[SoftwareFileUsageUpdateBatchByComputerIDUserIDSoftwareFileNameIDVersionCompanyNameDescriptionProductNameProductVersion]
GO
CREATE PROCEDURE dbo.[SoftwareFileUsageUpdateBatchByComputerIDUserIDSoftwareFileNameIDVersionCompanyNameDescriptionProductNameProductVersion]
AS
	DECLARE @count int

	CREATE INDEX [TempSoftwareFileUsageComputerIDUserIDSoftwareFileNameIDVersionCompanyNameDescriptionProductNameProductVersion]
		ON #SoftwareFileUsage (ComputerID, UserID, SoftwareFileNameID, Version, CompanyName, Description, ProductName, ProductVersion)

	UPDATE	[dbo].[SoftwareFileUsage]
	SET	LongName = t.LongName
	FROM	#SoftwareFileUsage AS t
	WHERE	SoftwareFileUsage.ComputerID = t.ComputerID
	  AND	SoftwareFileUsage.UserID = t.UserID
	  AND	SoftwareFileUsage.SoftwareFileNameID = t.SoftwareFileNameID
	  AND	SoftwareFileUsage.Version = t.Version
	  AND	SoftwareFileUsage.CompanyName = t.CompanyName
	  AND	SoftwareFileUsage.Description = t.Description
	  AND	SoftwareFileUsage.ProductName = t.ProductName
	  AND	SoftwareFileUsage.ProductVersion = t.ProductVersion
	SET @count = @@ROWCOUNT
	DROP TABLE #SoftwareFileUsage	-- Drop the temporary table
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[SoftwareFileUsagePutByComputerIDUserIDSoftwareFileNameIDVersionCompanyNameDescriptionProductNameProductVersion]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[SoftwareFileUsagePutByComputerIDUserIDSoftwareFileNameIDVersionCompanyNameDescriptionProductNameProductVersion]
GO
CREATE PROCEDURE [dbo].[SoftwareFileUsagePutByComputerIDUserIDSoftwareFileNameIDVersionCompanyNameDescriptionProductNameProductVersion]
	@ComputerID		int,
	@UserID			int,
	@SoftwareFileNameID	int,
	@Version		nvarchar(32),
	@CompanyName		nvarchar(50),
	@Description		nvarchar(1024),
	@ProductName		nvarchar(50),
	@ProductVersion		nvarchar(32),
	@LongName		nvarchar(4000) = NULL
AS
	DECLARE @ID	int

	SELECT	@ID = SoftwareFileUsageID
	FROM	SoftwareFileUsage
	WHERE	ComputerID = @ComputerID
	  AND	UserID = @UserID
	  AND	SoftwareFileNameID = @SoftwareFileNameID
	  AND	Version = @Version
	  AND	CompanyName = @CompanyName
	  AND	Description = @Description
	  AND	ProductName = @ProductName
	  AND	ProductVersion = @ProductVersion

	IF @ID IS NULL
		EXEC @ID = SoftwareFileUsageAdd @ComputerID,
			@UserID,
			@Version,
			@SoftwareFileNameID,
			@LongName,
			@CompanyName,
			@Description,
			@ProductName,
			@ProductVersion
	ELSE
		EXEC SoftwareFileUsageUpdateByComputerIDUserIDSoftwareFileNameIDVersionCompanyNameDescriptionProductNameProductVersion @ComputerID,
			@UserID,
			@SoftwareFileNameID,
			@Version,
			@CompanyName,
			@Description,
			@ProductName,
			@ProductVersion,
			@LongName

	RETURN @ID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[SoftwareFileUsagePutBatchByComputerIDUserIDSoftwareFileNameIDVersionCompanyNameDescriptionProductNameProductVersion]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[SoftwareFileUsagePutBatchByComputerIDUserIDSoftwareFileNameIDVersionCompanyNameDescriptionProductNameProductVersion]
GO
CREATE PROCEDURE [dbo].[SoftwareFileUsagePutBatchByComputerIDUserIDSoftwareFileNameIDVersionCompanyNameDescriptionProductNameProductVersion]
AS
	DECLARE @count AS int
	SET @count = 0

	CREATE INDEX [TempSoftwareFileUsageComputerIDUserIDSoftwareFileNameIDVersionCompanyNameDescriptionProductNameProductVersion]
		ON #SoftwareFileUsage (ComputerID, UserID, SoftwareFileNameID, Version, CompanyName, Description, ProductName, ProductVersion)

	BEGIN TRANSACTION
	UPDATE [dbo].[SoftwareFileUsage]
		SET	LongName = t.LongName
		FROM	#SoftwareFileUsage AS t
		WHERE	SoftwareFileUsage.ComputerID = t.ComputerID
		  AND	SoftwareFileUsage.UserID = t.UserID
		  AND	SoftwareFileUsage.SoftwareFileNameID = t.SoftwareFileNameID
		  AND	SoftwareFileUsage.Version = t.Version
		  AND	SoftwareFileUsage.CompanyName = t.CompanyName
		  AND	SoftwareFileUsage.Description = t.Description
		  AND	SoftwareFileUsage.ProductName = t.ProductName
		  AND	SoftwareFileUsage.ProductVersion = t.ProductVersion
	SET @count = @@ROWCOUNT

	INSERT [dbo].[SoftwareFileUsage] (
		ComputerID,
		UserID,
		Version,
		SoftwareFileNameID,
		LongName,
		CompanyName,
		Description,
		ProductName,
		ProductVersion
	)
		SELECT	ComputerID,
			UserID,
			Version,
			SoftwareFileNameID,
			LongName,
			CompanyName,
			Description,
			ProductName,
			ProductVersion
		FROM	#SoftwareFileUsage AS t
		WHERE NOT EXISTS(	-- Current record doesn't exist
			SELECT * FROM [dbo].[SoftwareFileUsage]
			WHERE	SoftwareFileUsage.ComputerID = t.ComputerID
			  AND	SoftwareFileUsage.UserID = t.UserID
			  AND	SoftwareFileUsage.SoftwareFileNameID = t.SoftwareFileNameID
			  AND	SoftwareFileUsage.Version = t.Version
			  AND	SoftwareFileUsage.CompanyName = t.CompanyName
			  AND	SoftwareFileUsage.Description = t.Description
			  AND	SoftwareFileUsage.ProductName = t.ProductName
			  AND	SoftwareFileUsage.ProductVersion = t.ProductVersion
		)
	SET @count = @count + @@ROWCOUNT
	DROP TABLE #SoftwareFileUsage	-- Drop the temporary table
	COMMIT WORK
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[SoftwareFileUsageRemoveBatch]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[SoftwareFileUsageRemoveBatch]
GO

CREATE PROCEDURE [dbo].[SoftwareFileUsageRemoveBatch]
AS

	CREATE INDEX [TempSoftwareFileUsageSoftwareFileUsageRemoveBatch]
		ON #SoftwareFileUsage (SoftwareFileUsageID)	

	-- Delete records from SoftwareFileUsage identified by fields of [TempSoftwareFileUsageSoftwareFileUsageRemoveBatch]
	DELETE [dbo].[SoftwareFileUsage]
	WHERE EXISTS(
			SELECT * FROM #SoftwareFileUsage AS t
			WHERE	SoftwareFileUsage.SoftwareFileUsageID = t.SoftwareFileUsageID
		)
	DROP TABLE #SoftwareFileUsage      -- Drop the temporary table
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[SoftwareFileUsageRemoveByComputerIDUserIDSoftwareFileNameIDVersionCompanyNameDescriptionProductNameProductVersion]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[SoftwareFileUsageRemoveByComputerIDUserIDSoftwareFileNameIDVersionCompanyNameDescriptionProductNameProductVersion]
GO
CREATE PROCEDURE [dbo].[SoftwareFileUsageRemoveByComputerIDUserIDSoftwareFileNameIDVersionCompanyNameDescriptionProductNameProductVersion]
	@ComputerID		int,
	@UserID			int,
	@SoftwareFileNameID	int,
	@Version		nvarchar(32),
	@CompanyName		nvarchar(50),
	@Description		nvarchar(1024),
	@ProductName		nvarchar(50),
	@ProductVersion		nvarchar(32)
AS
	-- SoftwareFileUsage deletes cascade to:
	--	SoftwareUsagePerWeek by FK_SoftwareUsagePerWeek_SoftwareFileUsage
	DELETE	[dbo].[SoftwareFileUsage]
	WHERE	ComputerID = @ComputerID
	  AND	UserID = @UserID
	  AND	SoftwareFileNameID = @SoftwareFileNameID
	  AND	Version = @Version
	  AND	CompanyName = @CompanyName
	  AND	Description = @Description
	  AND	ProductName = @ProductName
	  AND	ProductVersion = @ProductVersion
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[SoftwareFileUsageRemoveAll]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[SoftwareFileUsageRemoveAll]
GO
CREATE PROCEDURE [dbo].[SoftwareFileUsageRemoveAll]
	
AS
	DELETE	[dbo].[SoftwareFileUsage]
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[EventClassGetByID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[EventClassGetByID]
GO
CREATE PROCEDURE [dbo].[EventClassGetByID]
	@EventClassID		int
AS
	SELECT	EventClassID,
		[Name]
	FROM	[dbo].[EventClass]
	WHERE	EventClassID = @EventClassID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[EventClassGetAll]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[EventClassGetAll]
GO
CREATE PROCEDURE [dbo].[EventClassGetAll]
AS
	SELECT	EventClassID,
		[Name]
	FROM	[dbo].[EventClass]
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[EventClassAdd]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[EventClassAdd]
GO
CREATE PROCEDURE [dbo].[EventClassAdd]
	@Name			nvarchar(50)
AS
	INSERT INTO  dbo.EventClass (
		[Name]
	)
	VALUES (
		@Name
	)
	RETURN SCOPE_IDENTITY()
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[EventClassSchema]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[EventClassSchema]
GO
CREATE PROCEDURE [dbo].[EventClassSchema]
AS
	SELECT
	'IF OBJECT_ID(''tempdb..#EventClass'') IS NULL' + CAST(0x0A AS CHAR(1)) +
	'	CREATE TABLE #EventClass (' + CAST(0x0A AS CHAR(1)) +
	'		EventClassID		int NULL,' + CAST(0x0A AS CHAR(1)) +
	'		[Name]			nvarchar(50) COLLATE database_default NOT NULL' + CAST(0x0A AS CHAR(1)) +
	'	)' + CAST(0x0A AS CHAR(1)) +
	'ELSE' + CAST(0x0A AS CHAR(1)) +
	'	DELETE FROM #EventClass' + CAST(0x0A AS CHAR(1)) +
	'' AS SQL
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[EventClassTempAdd]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[EventClassTempAdd]
GO
CREATE PROCEDURE dbo.[EventClassTempAdd]
	@EventClassID		int,
	@Name			nvarchar(50)
AS
	INSERT INTO #EventClass (
		EventClassID,
		[Name]
	)
	VALUES (
		@EventClassID,
		@Name
	)
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[EventClassAddBatch]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[EventClassAddBatch]
GO
CREATE PROCEDURE dbo.[EventClassAddBatch]
AS
	DECLARE @count int
	INSERT dbo.EventClass (
		[Name]
	)
		SELECT	[Name]
		FROM #EventClass
	SET @count = @@ROWCOUNT
	DROP TABLE #EventClass	-- Drop temporary table
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[EventClassUpdateByID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[EventClassUpdateByID]
GO
CREATE PROCEDURE [dbo].[EventClassUpdateByID]
	@EventClassID		int,
	@Name			nvarchar(50)
AS
	DECLARE	@ID	int
	SET @ID = 0

	UPDATE	[dbo].[EventClass]
	SET	@ID = EventClassID,
		[Name] = @Name
	WHERE	EventClassID = @EventClassID
	RETURN @ID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[EventClassUpdateBatchByID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[EventClassUpdateBatchByID]
GO
CREATE PROCEDURE dbo.[EventClassUpdateBatchByID]
AS
	DECLARE @count int

	CREATE INDEX [TempEventClassID]
		ON #EventClass (EventClassID)

	UPDATE	[dbo].[EventClass]
	SET	[Name] = t.[Name]
	FROM	#EventClass AS t
	WHERE	EventClass.EventClassID = t.EventClassID
	SET @count = @@ROWCOUNT
	DROP TABLE #EventClass	-- Drop the temporary table
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[EventClassRemoveBatch]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[EventClassRemoveBatch]
GO

CREATE PROCEDURE [dbo].[EventClassRemoveBatch]
AS

	CREATE INDEX [TempEventClassEventClassRemoveBatch]
		ON #EventClass (EventClassID)	

	-- Delete records from EventClass identified by fields of [TempEventClassEventClassRemoveBatch]
	DELETE [dbo].[EventClass]
	WHERE EXISTS(
			SELECT * FROM #EventClass AS t
			WHERE	EventClass.EventClassID = t.EventClassID
		)
	DROP TABLE #EventClass      -- Drop the temporary table
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[EventClassRemoveByID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[EventClassRemoveByID]
GO
CREATE PROCEDURE [dbo].[EventClassRemoveByID]
	@EventClassID		int
AS
	-- EventClass deletes cascade to:
	--	DeviceEvent by FK_DeviceEvent_EventClass
	--	SessionStateEvent by FK_SessionStateEvent_EventClass
	--	GeneralSecurityEvent by FK_GeneralSecurityEvent_EventClass
	DELETE	[dbo].[EventClass]
	WHERE	EventClassID = @EventClassID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[EventClassRemoveAll]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[EventClassRemoveAll]
GO
CREATE PROCEDURE [dbo].[EventClassRemoveAll]
	
AS
	DELETE	[dbo].[EventClass]
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[DeviceEventGetByID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[DeviceEventGetByID]
GO
CREATE PROCEDURE [dbo].[DeviceEventGetByID]
	@DeviceEventID		int
AS
	SELECT	DeviceEventID,
		ComputerID,
		UserID,
		[DateTime],
		DeviceName,
		DeviceClass,
		DeviceID,
		Enabled,
		EventID,
		EventDescription
	FROM	[dbo].[DeviceEvent]
	WHERE	DeviceEventID = @DeviceEventID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[DeviceEventGetByComputerIDUserIDDateTimeDeviceIDEventID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[DeviceEventGetByComputerIDUserIDDateTimeDeviceIDEventID]
GO
CREATE PROCEDURE [dbo].[DeviceEventGetByComputerIDUserIDDateTimeDeviceIDEventID]
	@ComputerID		int,
	@UserID			int = NULL,
	@DateTime		datetime,
	@DeviceID		nvarchar(128),
	@EventID		int
AS
	SELECT	DeviceEventID,
		ComputerID,
		UserID,
		[DateTime],
		DeviceName,
		DeviceClass,
		DeviceID,
		Enabled,
		EventID,
		EventDescription
	FROM	[dbo].[DeviceEvent]
	WHERE	ComputerID = @ComputerID
	  AND	(UserID = @UserID OR (UserID IS NULL AND @UserID IS NULL))
	  AND	[DateTime] = @DateTime
	  AND	DeviceID = @DeviceID
	  AND	EventID = @EventID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[DeviceEventGetAllByComputerID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[DeviceEventGetAllByComputerID]
GO
CREATE PROCEDURE [dbo].[DeviceEventGetAllByComputerID]
	@ComputerID		int
AS
	SELECT	DeviceEventID,
		ComputerID,
		UserID,
		[DateTime],
		DeviceName,
		DeviceClass,
		DeviceID,
		Enabled,
		EventID,
		EventDescription
	FROM	[dbo].[DeviceEvent]
	WHERE	ComputerID = @ComputerID
	ORDER BY UserID, [DateTime], DeviceID, EventID
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[DeviceEventGetAll]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[DeviceEventGetAll]
GO
CREATE PROCEDURE [dbo].[DeviceEventGetAll]
AS
	SELECT	DeviceEventID,
		ComputerID,
		UserID,
		[DateTime],
		DeviceName,
		DeviceClass,
		DeviceID,
		Enabled,
		EventID,
		EventDescription
	FROM	[dbo].[DeviceEvent]
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[DeviceEventAdd]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[DeviceEventAdd]
GO
CREATE PROCEDURE [dbo].[DeviceEventAdd]
	@ComputerID		int,
	@UserID			int = NULL,
	@DateTime		datetime,
	@DeviceName		nvarchar(256),
	@DeviceClass		nvarchar(256),
	@DeviceID		nvarchar(128),
	@Enabled		bit = NULL,
	@EventID		int,
	@EventDescription	nvarchar(256)
AS
	INSERT INTO  dbo.DeviceEvent (
		ComputerID,
		UserID,
		[DateTime],
		DeviceName,
		DeviceClass,
		DeviceID,
		Enabled,
		EventID,
		EventDescription
	)
	VALUES (
		@ComputerID,
		@UserID,
		@DateTime,
		@DeviceName,
		@DeviceClass,
		@DeviceID,
		@Enabled,
		@EventID,
		@EventDescription
	)
	RETURN SCOPE_IDENTITY()
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[DeviceEventBind]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[DeviceEventBind]
GO
CREATE PROCEDURE [dbo].[DeviceEventBind]
	@ComputerID		int,
	@UserID			int = NULL,
	@DateTime		datetime,
	@DeviceName		nvarchar(256),
	@DeviceClass		nvarchar(256),
	@DeviceID		nvarchar(128),
	@Enabled		bit = NULL,
	@EventID		int,
	@EventDescription	nvarchar(256)
AS
	DECLARE	@ID	int

	SELECT	@ID = DeviceEventID
	FROM	[dbo].[DeviceEvent]
	WHERE	ComputerID = @ComputerID
	  AND	(UserID = @UserID OR (UserID IS NULL AND @UserID IS NULL))
	  AND	[DateTime] = @DateTime
	  AND	DeviceID = @DeviceID
	  AND	EventID = @EventID

	IF @ID IS NULL
		EXEC @ID = DeviceEventAdd @ComputerID,
			@UserID,
			@DateTime,
			@DeviceName,
			@DeviceClass,
			@DeviceID,
			@Enabled,
			@EventID,
			@EventDescription

	RETURN @ID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[DeviceEventSchema]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[DeviceEventSchema]
GO
CREATE PROCEDURE [dbo].[DeviceEventSchema]
AS
	SELECT
	'IF OBJECT_ID(''tempdb..#DeviceEvent'') IS NULL' + CAST(0x0A AS CHAR(1)) +
	'	CREATE TABLE #DeviceEvent (' + CAST(0x0A AS CHAR(1)) +
	'		DeviceEventID		int NULL,' + CAST(0x0A AS CHAR(1)) +
	'		ComputerID		int NOT NULL,' + CAST(0x0A AS CHAR(1)) +
	'		UserID			int NULL,' + CAST(0x0A AS CHAR(1)) +
	'		[DateTime]		datetime NOT NULL,' + CAST(0x0A AS CHAR(1)) +
	'		DeviceName		nvarchar(256) COLLATE database_default NOT NULL,' + CAST(0x0A AS CHAR(1)) +
	'		DeviceClass		nvarchar(256) COLLATE database_default NOT NULL,' + CAST(0x0A AS CHAR(1)) +
	'		DeviceID		nvarchar(128) COLLATE database_default NOT NULL,' + CAST(0x0A AS CHAR(1)) +
	'		Enabled			bit NULL,' + CAST(0x0A AS CHAR(1)) +
	'		EventID			int NOT NULL,' + CAST(0x0A AS CHAR(1)) +
	'		EventDescription	nvarchar(256) COLLATE database_default NOT NULL' + CAST(0x0A AS CHAR(1)) +
	'	)' + CAST(0x0A AS CHAR(1)) +
	'ELSE' + CAST(0x0A AS CHAR(1)) +
	'	DELETE FROM #DeviceEvent' + CAST(0x0A AS CHAR(1)) +
	'' AS SQL
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[DeviceEventTempAdd]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[DeviceEventTempAdd]
GO
CREATE PROCEDURE dbo.[DeviceEventTempAdd]
	@DeviceEventID		int,
	@ComputerID		int,
	@UserID			int = NULL,
	@DateTime		datetime,
	@DeviceName		nvarchar(256),
	@DeviceClass		nvarchar(256),
	@DeviceID		nvarchar(128),
	@Enabled		bit = NULL,
	@EventID		int,
	@EventDescription	nvarchar(256)
AS
	INSERT INTO #DeviceEvent (
		DeviceEventID,
		ComputerID,
		UserID,
		[DateTime],
		DeviceName,
		DeviceClass,
		DeviceID,
		Enabled,
		EventID,
		EventDescription
	)
	VALUES (
		@DeviceEventID,
		@ComputerID,
		@UserID,
		@DateTime,
		@DeviceName,
		@DeviceClass,
		@DeviceID,
		@Enabled,
		@EventID,
		@EventDescription
	)
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[DeviceEventAddBatch]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[DeviceEventAddBatch]
GO
CREATE PROCEDURE dbo.[DeviceEventAddBatch]
AS
	DECLARE @count int
	INSERT dbo.DeviceEvent (
		ComputerID,
		UserID,
		[DateTime],
		DeviceName,
		DeviceClass,
		DeviceID,
		Enabled,
		EventID,
		EventDescription
	)
		SELECT	ComputerID,
			UserID,
			[DateTime],
			DeviceName,
			DeviceClass,
			DeviceID,
			Enabled,
			EventID,
			EventDescription
		FROM #DeviceEvent
	SET @count = @@ROWCOUNT
	DROP TABLE #DeviceEvent	-- Drop temporary table
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[DeviceEventUpdateByID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[DeviceEventUpdateByID]
GO
CREATE PROCEDURE [dbo].[DeviceEventUpdateByID]
	@DeviceEventID		int,
	@ComputerID		int,
	@UserID			int = NULL,
	@DateTime		datetime,
	@DeviceName		nvarchar(256),
	@DeviceClass		nvarchar(256),
	@DeviceID		nvarchar(128),
	@Enabled		bit = NULL,
	@EventID		int,
	@EventDescription	nvarchar(256)
AS
	DECLARE	@ID	int
	SET @ID = 0

	UPDATE	[dbo].[DeviceEvent]
	SET	@ID = DeviceEventID,
		ComputerID = @ComputerID,
		UserID = @UserID,
		[DateTime] = @DateTime,
		DeviceName = @DeviceName,
		DeviceClass = @DeviceClass,
		DeviceID = @DeviceID,
		Enabled = @Enabled,
		EventID = @EventID,
		EventDescription = @EventDescription
	WHERE	DeviceEventID = @DeviceEventID
	RETURN @ID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[DeviceEventUpdateBatchByID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[DeviceEventUpdateBatchByID]
GO
CREATE PROCEDURE dbo.[DeviceEventUpdateBatchByID]
AS
	DECLARE @count int

	CREATE INDEX [TempDeviceEventID]
		ON #DeviceEvent (DeviceEventID)

	UPDATE	[dbo].[DeviceEvent]
	SET	ComputerID = t.ComputerID,
		UserID = t.UserID,
		[DateTime] = t.[DateTime],
		DeviceName = t.DeviceName,
		DeviceClass = t.DeviceClass,
		DeviceID = t.DeviceID,
		Enabled = t.Enabled,
		EventID = t.EventID,
		EventDescription = t.EventDescription
	FROM	#DeviceEvent AS t
	WHERE	DeviceEvent.DeviceEventID = t.DeviceEventID
	SET @count = @@ROWCOUNT
	DROP TABLE #DeviceEvent	-- Drop the temporary table
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[DeviceEventUpdateByComputerIDUserIDDateTimeDeviceIDEventID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[DeviceEventUpdateByComputerIDUserIDDateTimeDeviceIDEventID]
GO
CREATE PROCEDURE [dbo].[DeviceEventUpdateByComputerIDUserIDDateTimeDeviceIDEventID]
	@ComputerID		int,
	@UserID			int = NULL,
	@DateTime		datetime,
	@DeviceID		nvarchar(128),
	@EventID		int,
	@DeviceName		nvarchar(256),
	@DeviceClass		nvarchar(256),
	@Enabled		bit = NULL,
	@EventDescription	nvarchar(256)
AS
	DECLARE	@ID	int
	SET @ID = 0

	UPDATE	[dbo].[DeviceEvent]
	SET	@ID = DeviceEventID,
		DeviceName = @DeviceName,
		DeviceClass = @DeviceClass,
		Enabled = @Enabled,
		EventDescription = @EventDescription
	WHERE	ComputerID = @ComputerID
	  AND	(UserID = @UserID OR (UserID IS NULL AND @UserID IS NULL))
	  AND	[DateTime] = @DateTime
	  AND	DeviceID = @DeviceID
	  AND	EventID = @EventID
	RETURN @ID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[DeviceEventUpdateBatchByComputerIDUserIDDateTimeDeviceIDEventID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[DeviceEventUpdateBatchByComputerIDUserIDDateTimeDeviceIDEventID]
GO
CREATE PROCEDURE dbo.[DeviceEventUpdateBatchByComputerIDUserIDDateTimeDeviceIDEventID]
AS
	DECLARE @count int

	CREATE INDEX [TempDeviceEventComputerIDUserIDDateTimeDeviceIDEventID]
		ON #DeviceEvent (ComputerID, UserID, [DateTime], DeviceID, EventID)

	UPDATE	[dbo].[DeviceEvent]
	SET	DeviceName = t.DeviceName,
		DeviceClass = t.DeviceClass,
		Enabled = t.Enabled,
		EventDescription = t.EventDescription
	FROM	#DeviceEvent AS t
	WHERE	DeviceEvent.ComputerID = t.ComputerID
	  AND	(DeviceEvent.UserID = t.UserID OR (DeviceEvent.UserID IS NULL AND t.UserID IS NULL))
	  AND	DeviceEvent.[DateTime] = t.[DateTime]
	  AND	DeviceEvent.DeviceID = t.DeviceID
	  AND	DeviceEvent.EventID = t.EventID
	SET @count = @@ROWCOUNT
	DROP TABLE #DeviceEvent	-- Drop the temporary table
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[DeviceEventPutByComputerIDUserIDDateTimeDeviceIDEventID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[DeviceEventPutByComputerIDUserIDDateTimeDeviceIDEventID]
GO
CREATE PROCEDURE [dbo].[DeviceEventPutByComputerIDUserIDDateTimeDeviceIDEventID]
	@ComputerID		int,
	@UserID			int = NULL,
	@DateTime		datetime,
	@DeviceID		nvarchar(128),
	@EventID		int,
	@DeviceName		nvarchar(256),
	@DeviceClass		nvarchar(256),
	@Enabled		bit = NULL,
	@EventDescription	nvarchar(256)
AS
	DECLARE @ID	int

	SELECT	@ID = DeviceEventID
	FROM	DeviceEvent
	WHERE	ComputerID = @ComputerID
	  AND	(UserID = @UserID OR (UserID IS NULL AND @UserID IS NULL))
	  AND	[DateTime] = @DateTime
	  AND	DeviceID = @DeviceID
	  AND	EventID = @EventID

	IF @ID IS NULL
		EXEC @ID = DeviceEventAdd @ComputerID,
			@UserID,
			@DateTime,
			@DeviceName,
			@DeviceClass,
			@DeviceID,
			@Enabled,
			@EventID,
			@EventDescription
	ELSE
		EXEC DeviceEventUpdateByComputerIDUserIDDateTimeDeviceIDEventID @ComputerID,
			@UserID,
			@DateTime,
			@DeviceID,
			@EventID,
			@DeviceName,
			@DeviceClass,
			@Enabled,
			@EventDescription

	RETURN @ID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[DeviceEventPutBatchByComputerIDUserIDDateTimeDeviceIDEventID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[DeviceEventPutBatchByComputerIDUserIDDateTimeDeviceIDEventID]
GO
CREATE PROCEDURE [dbo].[DeviceEventPutBatchByComputerIDUserIDDateTimeDeviceIDEventID]
AS
	DECLARE @count AS int
	SET @count = 0

	CREATE INDEX [TempDeviceEventComputerIDUserIDDateTimeDeviceIDEventID]
		ON #DeviceEvent (ComputerID, UserID, [DateTime], DeviceID, EventID)

	BEGIN TRANSACTION
	UPDATE [dbo].[DeviceEvent]
		SET	DeviceName = t.DeviceName,
			DeviceClass = t.DeviceClass,
			Enabled = t.Enabled,
			EventDescription = t.EventDescription
		FROM	#DeviceEvent AS t
		WHERE	DeviceEvent.ComputerID = t.ComputerID
		  AND	(DeviceEvent.UserID = t.UserID OR (DeviceEvent.UserID IS NULL AND t.UserID IS NULL))
		  AND	DeviceEvent.[DateTime] = t.[DateTime]
		  AND	DeviceEvent.DeviceID = t.DeviceID
		  AND	DeviceEvent.EventID = t.EventID
	SET @count = @@ROWCOUNT

	INSERT [dbo].[DeviceEvent] (
		ComputerID,
		UserID,
		[DateTime],
		DeviceName,
		DeviceClass,
		DeviceID,
		Enabled,
		EventID,
		EventDescription
	)
		SELECT	ComputerID,
			UserID,
			[DateTime],
			DeviceName,
			DeviceClass,
			DeviceID,
			Enabled,
			EventID,
			EventDescription
		FROM	#DeviceEvent AS t
		WHERE NOT EXISTS(	-- Current record doesn't exist
			SELECT * FROM [dbo].[DeviceEvent]
			WHERE	DeviceEvent.ComputerID = t.ComputerID
			  AND	(DeviceEvent.UserID = t.UserID OR (DeviceEvent.UserID IS NULL AND t.UserID IS NULL))
			  AND	DeviceEvent.[DateTime] = t.[DateTime]
			  AND	DeviceEvent.DeviceID = t.DeviceID
			  AND	DeviceEvent.EventID = t.EventID
		)
	SET @count = @count + @@ROWCOUNT
	DROP TABLE #DeviceEvent	-- Drop the temporary table
	COMMIT WORK
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[DeviceEventRemoveBatch]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[DeviceEventRemoveBatch]
GO

CREATE PROCEDURE [dbo].[DeviceEventRemoveBatch]
AS

	CREATE INDEX [TempDeviceEventDeviceEventRemoveBatch]
		ON #DeviceEvent (DeviceEventID)	

	-- Delete records from DeviceEvent identified by fields of [TempDeviceEventDeviceEventRemoveBatch]
	DELETE [dbo].[DeviceEvent]
	WHERE EXISTS(
			SELECT * FROM #DeviceEvent AS t
			WHERE	DeviceEvent.DeviceEventID = t.DeviceEventID
		)
	DROP TABLE #DeviceEvent      -- Drop the temporary table
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[DeviceEventRemoveByID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[DeviceEventRemoveByID]
GO
CREATE PROCEDURE [dbo].[DeviceEventRemoveByID]
	@DeviceEventID		int
AS
	DELETE	[dbo].[DeviceEvent]
	WHERE	DeviceEventID = @DeviceEventID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[DeviceEventRemoveAll]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[DeviceEventRemoveAll]
GO
CREATE PROCEDURE [dbo].[DeviceEventRemoveAll]
	
AS
	DELETE	[dbo].[DeviceEvent]
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[SessionStateEventGetByID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[SessionStateEventGetByID]
GO
CREATE PROCEDURE [dbo].[SessionStateEventGetByID]
	@SessionStateEventID	int
AS
	SELECT	SessionStateEventID,
		ComputerID,
		UserID,
		[DateTime],
		EventID,
		Client,
		EventDescription
	FROM	[dbo].[SessionStateEvent]
	WHERE	SessionStateEventID = @SessionStateEventID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[SessionStateEventGetByComputerIDUserIDDateTimeEventID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[SessionStateEventGetByComputerIDUserIDDateTimeEventID]
GO
CREATE PROCEDURE [dbo].[SessionStateEventGetByComputerIDUserIDDateTimeEventID]
	@ComputerID		int,
	@UserID			int,
	@DateTime		datetime,
	@EventID		int
AS
	SELECT	SessionStateEventID,
		ComputerID,
		UserID,
		[DateTime],
		EventID,
		Client,
		EventDescription
	FROM	[dbo].[SessionStateEvent]
	WHERE	ComputerID = @ComputerID
	  AND	UserID = @UserID
	  AND	[DateTime] = @DateTime
	  AND	EventID = @EventID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[SessionStateEventGetAllByComputerID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[SessionStateEventGetAllByComputerID]
GO
CREATE PROCEDURE [dbo].[SessionStateEventGetAllByComputerID]
	@ComputerID		int
AS
	SELECT	SessionStateEventID,
		ComputerID,
		UserID,
		[DateTime],
		EventID,
		Client,
		EventDescription
	FROM	[dbo].[SessionStateEvent]
	WHERE	ComputerID = @ComputerID
	ORDER BY UserID, [DateTime], EventID
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[SessionStateEventGetAll]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[SessionStateEventGetAll]
GO
CREATE PROCEDURE [dbo].[SessionStateEventGetAll]
AS
	SELECT	SessionStateEventID,
		ComputerID,
		UserID,
		[DateTime],
		EventID,
		Client,
		EventDescription
	FROM	[dbo].[SessionStateEvent]
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[SessionStateEventAdd]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[SessionStateEventAdd]
GO
CREATE PROCEDURE [dbo].[SessionStateEventAdd]
	@ComputerID		int,
	@UserID			int,
	@DateTime		datetime,
	@EventID		int,
	@Client			nvarchar(56),
	@EventDescription	nvarchar(256)
AS
	INSERT INTO  dbo.SessionStateEvent (
		ComputerID,
		UserID,
		[DateTime],
		EventID,
		Client,
		EventDescription
	)
	VALUES (
		@ComputerID,
		@UserID,
		@DateTime,
		@EventID,
		@Client,
		@EventDescription
	)
	RETURN SCOPE_IDENTITY()
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[SessionStateEventBind]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[SessionStateEventBind]
GO
CREATE PROCEDURE [dbo].[SessionStateEventBind]
	@ComputerID		int,
	@UserID			int,
	@DateTime		datetime,
	@EventID		int,
	@Client			nvarchar(56),
	@EventDescription	nvarchar(256)
AS
	DECLARE	@ID	int

	SELECT	@ID = SessionStateEventID
	FROM	[dbo].[SessionStateEvent]
	WHERE	ComputerID = @ComputerID
	  AND	UserID = @UserID
	  AND	[DateTime] = @DateTime
	  AND	EventID = @EventID

	IF @ID IS NULL
		EXEC @ID = SessionStateEventAdd @ComputerID,
			@UserID,
			@DateTime,
			@EventID,
			@Client,
			@EventDescription

	RETURN @ID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[SessionStateEventSchema]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[SessionStateEventSchema]
GO
CREATE PROCEDURE [dbo].[SessionStateEventSchema]
AS
	SELECT
	'IF OBJECT_ID(''tempdb..#SessionStateEvent'') IS NULL' + CAST(0x0A AS CHAR(1)) +
	'	CREATE TABLE #SessionStateEvent (' + CAST(0x0A AS CHAR(1)) +
	'		SessionStateEventID	int NULL,' + CAST(0x0A AS CHAR(1)) +
	'		ComputerID		int NOT NULL,' + CAST(0x0A AS CHAR(1)) +
	'		UserID			int NOT NULL,' + CAST(0x0A AS CHAR(1)) +
	'		[DateTime]		datetime NOT NULL,' + CAST(0x0A AS CHAR(1)) +
	'		EventID			int NOT NULL,' + CAST(0x0A AS CHAR(1)) +
	'		Client			nvarchar(56) COLLATE database_default NOT NULL,' + CAST(0x0A AS CHAR(1)) +
	'		EventDescription	nvarchar(256) COLLATE database_default NOT NULL' + CAST(0x0A AS CHAR(1)) +
	'	)' + CAST(0x0A AS CHAR(1)) +
	'ELSE' + CAST(0x0A AS CHAR(1)) +
	'	DELETE FROM #SessionStateEvent' + CAST(0x0A AS CHAR(1)) +
	'' AS SQL
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[SessionStateEventTempAdd]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[SessionStateEventTempAdd]
GO
CREATE PROCEDURE dbo.[SessionStateEventTempAdd]
	@SessionStateEventID	int,
	@ComputerID		int,
	@UserID			int,
	@DateTime		datetime,
	@EventID		int,
	@Client			nvarchar(56),
	@EventDescription	nvarchar(256)
AS
	INSERT INTO #SessionStateEvent (
		SessionStateEventID,
		ComputerID,
		UserID,
		[DateTime],
		EventID,
		Client,
		EventDescription
	)
	VALUES (
		@SessionStateEventID,
		@ComputerID,
		@UserID,
		@DateTime,
		@EventID,
		@Client,
		@EventDescription
	)
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[SessionStateEventAddBatch]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[SessionStateEventAddBatch]
GO
CREATE PROCEDURE dbo.[SessionStateEventAddBatch]
AS
	DECLARE @count int
	INSERT dbo.SessionStateEvent (
		ComputerID,
		UserID,
		[DateTime],
		EventID,
		Client,
		EventDescription
	)
		SELECT	ComputerID,
			UserID,
			[DateTime],
			EventID,
			Client,
			EventDescription
		FROM #SessionStateEvent
	SET @count = @@ROWCOUNT
	DROP TABLE #SessionStateEvent	-- Drop temporary table
	RETURN @count
GO

/*
Add new SessionStateEvent bound to
	User using UserOUID, UserCN
	with ComputerID, DateTime, EventID, Client, EventDescription
*/

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[SessionStateEventUpdateByID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[SessionStateEventUpdateByID]
GO
CREATE PROCEDURE [dbo].[SessionStateEventUpdateByID]
	@SessionStateEventID	int,
	@ComputerID		int,
	@UserID			int,
	@DateTime		datetime,
	@EventID		int,
	@Client			nvarchar(56),
	@EventDescription	nvarchar(256)
AS
	DECLARE	@ID	int
	SET @ID = 0

	UPDATE	[dbo].[SessionStateEvent]
	SET	@ID = SessionStateEventID,
		ComputerID = @ComputerID,
		UserID = @UserID,
		[DateTime] = @DateTime,
		EventID = @EventID,
		Client = @Client,
		EventDescription = @EventDescription
	WHERE	SessionStateEventID = @SessionStateEventID
	RETURN @ID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[SessionStateEventUpdateBatchByID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[SessionStateEventUpdateBatchByID]
GO
CREATE PROCEDURE dbo.[SessionStateEventUpdateBatchByID]
AS
	DECLARE @count int

	CREATE INDEX [TempSessionStateEventID]
		ON #SessionStateEvent (SessionStateEventID)

	UPDATE	[dbo].[SessionStateEvent]
	SET	ComputerID = t.ComputerID,
		UserID = t.UserID,
		[DateTime] = t.[DateTime],
		EventID = t.EventID,
		Client = t.Client,
		EventDescription = t.EventDescription
	FROM	#SessionStateEvent AS t
	WHERE	SessionStateEvent.SessionStateEventID = t.SessionStateEventID
	SET @count = @@ROWCOUNT
	DROP TABLE #SessionStateEvent	-- Drop the temporary table
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[SessionStateEventUpdateByComputerIDUserIDDateTimeEventID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[SessionStateEventUpdateByComputerIDUserIDDateTimeEventID]
GO
CREATE PROCEDURE [dbo].[SessionStateEventUpdateByComputerIDUserIDDateTimeEventID]
	@ComputerID		int,
	@UserID			int,
	@DateTime		datetime,
	@EventID		int,
	@Client			nvarchar(56),
	@EventDescription	nvarchar(256)
AS
	DECLARE	@ID	int
	SET @ID = 0

	UPDATE	[dbo].[SessionStateEvent]
	SET	@ID = SessionStateEventID,
		Client = @Client,
		EventDescription = @EventDescription
	WHERE	ComputerID = @ComputerID
	  AND	UserID = @UserID
	  AND	[DateTime] = @DateTime
	  AND	EventID = @EventID
	RETURN @ID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[SessionStateEventUpdateBatchByComputerIDUserIDDateTimeEventID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[SessionStateEventUpdateBatchByComputerIDUserIDDateTimeEventID]
GO
CREATE PROCEDURE dbo.[SessionStateEventUpdateBatchByComputerIDUserIDDateTimeEventID]
AS
	DECLARE @count int

	CREATE INDEX [TempSessionStateEventComputerIDUserIDDateTimeEventID]
		ON #SessionStateEvent (ComputerID, UserID, [DateTime], EventID)

	UPDATE	[dbo].[SessionStateEvent]
	SET	Client = t.Client,
		EventDescription = t.EventDescription
	FROM	#SessionStateEvent AS t
	WHERE	SessionStateEvent.ComputerID = t.ComputerID
	  AND	SessionStateEvent.UserID = t.UserID
	  AND	SessionStateEvent.[DateTime] = t.[DateTime]
	  AND	SessionStateEvent.EventID = t.EventID
	SET @count = @@ROWCOUNT
	DROP TABLE #SessionStateEvent	-- Drop the temporary table
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[SessionStateEventPutByComputerIDUserIDDateTimeEventID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[SessionStateEventPutByComputerIDUserIDDateTimeEventID]
GO
CREATE PROCEDURE [dbo].[SessionStateEventPutByComputerIDUserIDDateTimeEventID]
	@ComputerID		int,
	@UserID			int,
	@DateTime		datetime,
	@EventID		int,
	@Client			nvarchar(56),
	@EventDescription	nvarchar(256)
AS
	DECLARE @ID	int

	SELECT	@ID = SessionStateEventID
	FROM	SessionStateEvent
	WHERE	ComputerID = @ComputerID
	  AND	UserID = @UserID
	  AND	[DateTime] = @DateTime
	  AND	EventID = @EventID

	IF @ID IS NULL
		EXEC @ID = SessionStateEventAdd @ComputerID,
			@UserID,
			@DateTime,
			@EventID,
			@Client,
			@EventDescription
	ELSE
		EXEC SessionStateEventUpdateByComputerIDUserIDDateTimeEventID @ComputerID,
			@UserID,
			@DateTime,
			@EventID,
			@Client,
			@EventDescription

	RETURN @ID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[SessionStateEventPutBatchByComputerIDUserIDDateTimeEventID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[SessionStateEventPutBatchByComputerIDUserIDDateTimeEventID]
GO
CREATE PROCEDURE [dbo].[SessionStateEventPutBatchByComputerIDUserIDDateTimeEventID]
AS
	DECLARE @count AS int
	SET @count = 0

	CREATE INDEX [TempSessionStateEventComputerIDUserIDDateTimeEventID]
		ON #SessionStateEvent (ComputerID, UserID, [DateTime], EventID)

	BEGIN TRANSACTION
	UPDATE [dbo].[SessionStateEvent]
		SET	Client = t.Client,
			EventDescription = t.EventDescription
		FROM	#SessionStateEvent AS t
		WHERE	SessionStateEvent.ComputerID = t.ComputerID
		  AND	SessionStateEvent.UserID = t.UserID
		  AND	SessionStateEvent.[DateTime] = t.[DateTime]
		  AND	SessionStateEvent.EventID = t.EventID
	SET @count = @@ROWCOUNT

	INSERT [dbo].[SessionStateEvent] (
		ComputerID,
		UserID,
		[DateTime],
		EventID,
		Client,
		EventDescription
	)
		SELECT	ComputerID,
			UserID,
			[DateTime],
			EventID,
			Client,
			EventDescription
		FROM	#SessionStateEvent AS t
		WHERE NOT EXISTS(	-- Current record doesn't exist
			SELECT * FROM [dbo].[SessionStateEvent]
			WHERE	SessionStateEvent.ComputerID = t.ComputerID
			  AND	SessionStateEvent.UserID = t.UserID
			  AND	SessionStateEvent.[DateTime] = t.[DateTime]
			  AND	SessionStateEvent.EventID = t.EventID
		)
	SET @count = @count + @@ROWCOUNT
	DROP TABLE #SessionStateEvent	-- Drop the temporary table
	COMMIT WORK
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[SessionStateEventRemoveBatch]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[SessionStateEventRemoveBatch]
GO

CREATE PROCEDURE [dbo].[SessionStateEventRemoveBatch]
AS

	CREATE INDEX [TempSessionStateEventSessionStateEventRemoveBatch]
		ON #SessionStateEvent (SessionStateEventID)	

	-- Delete records from SessionStateEvent identified by fields of [TempSessionStateEventSessionStateEventRemoveBatch]
	DELETE [dbo].[SessionStateEvent]
	WHERE EXISTS(
			SELECT * FROM #SessionStateEvent AS t
			WHERE	SessionStateEvent.SessionStateEventID = t.SessionStateEventID
		)
	DROP TABLE #SessionStateEvent      -- Drop the temporary table
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[SessionStateEventRemoveByID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[SessionStateEventRemoveByID]
GO
CREATE PROCEDURE [dbo].[SessionStateEventRemoveByID]
	@SessionStateEventID	int
AS
	DELETE	[dbo].[SessionStateEvent]
	WHERE	SessionStateEventID = @SessionStateEventID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[SessionStateEventRemoveAll]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[SessionStateEventRemoveAll]
GO
CREATE PROCEDURE [dbo].[SessionStateEventRemoveAll]
	
AS
	DELETE	[dbo].[SessionStateEvent]
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[GeneralSecurityEventGetByID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[GeneralSecurityEventGetByID]
GO
CREATE PROCEDURE [dbo].[GeneralSecurityEventGetByID]
	@GeneralSecurityEventID	int
AS
	SELECT	GeneralSecurityEventID,
		ComputerID,
		UserID,
		[DateTime],
		Allowed,
		Setting,
		EventID,
		EventDescription
	FROM	[dbo].[GeneralSecurityEvent]
	WHERE	GeneralSecurityEventID = @GeneralSecurityEventID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[GeneralSecurityEventGetByComputerIDUserIDDateTimeEventID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[GeneralSecurityEventGetByComputerIDUserIDDateTimeEventID]
GO
CREATE PROCEDURE [dbo].[GeneralSecurityEventGetByComputerIDUserIDDateTimeEventID]
	@ComputerID		int,
	@UserID			int,
	@DateTime		datetime,
	@EventID		int
AS
	SELECT	GeneralSecurityEventID,
		ComputerID,
		UserID,
		[DateTime],
		Allowed,
		Setting,
		EventID,
		EventDescription
	FROM	[dbo].[GeneralSecurityEvent]
	WHERE	ComputerID = @ComputerID
	  AND	UserID = @UserID
	  AND	[DateTime] = @DateTime
	  AND	EventID = @EventID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[GeneralSecurityEventGetAllByComputerID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[GeneralSecurityEventGetAllByComputerID]
GO
CREATE PROCEDURE [dbo].[GeneralSecurityEventGetAllByComputerID]
	@ComputerID		int
AS
	SELECT	GeneralSecurityEventID,
		ComputerID,
		UserID,
		[DateTime],
		Allowed,
		Setting,
		EventID,
		EventDescription
	FROM	[dbo].[GeneralSecurityEvent]
	WHERE	ComputerID = @ComputerID
	ORDER BY UserID, [DateTime], EventID
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[GeneralSecurityEventGetAll]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[GeneralSecurityEventGetAll]
GO
CREATE PROCEDURE [dbo].[GeneralSecurityEventGetAll]
AS
	SELECT	GeneralSecurityEventID,
		ComputerID,
		UserID,
		[DateTime],
		Allowed,
		Setting,
		EventID,
		EventDescription
	FROM	[dbo].[GeneralSecurityEvent]
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[GeneralSecurityEventAdd]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[GeneralSecurityEventAdd]
GO
CREATE PROCEDURE [dbo].[GeneralSecurityEventAdd]
	@ComputerID		int,
	@UserID			int,
	@DateTime		datetime,
	@Allowed		bit = NULL,
	@Setting		nvarchar(128),
	@EventID		int,
	@EventDescription	nvarchar(256)
AS
	INSERT INTO  dbo.GeneralSecurityEvent (
		ComputerID,
		UserID,
		[DateTime],
		Allowed,
		Setting,
		EventID,
		EventDescription
	)
	VALUES (
		@ComputerID,
		@UserID,
		@DateTime,
		@Allowed,
		@Setting,
		@EventID,
		@EventDescription
	)
	RETURN SCOPE_IDENTITY()
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[GeneralSecurityEventBind]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[GeneralSecurityEventBind]
GO
CREATE PROCEDURE [dbo].[GeneralSecurityEventBind]
	@ComputerID		int,
	@UserID			int,
	@DateTime		datetime,
	@Allowed		bit = NULL,
	@Setting		nvarchar(128),
	@EventID		int,
	@EventDescription	nvarchar(256)
AS
	DECLARE	@ID	int

	SELECT	@ID = GeneralSecurityEventID
	FROM	[dbo].[GeneralSecurityEvent]
	WHERE	ComputerID = @ComputerID
	  AND	UserID = @UserID
	  AND	[DateTime] = @DateTime
	  AND	EventID = @EventID

	IF @ID IS NULL
		EXEC @ID = GeneralSecurityEventAdd @ComputerID,
			@UserID,
			@DateTime,
			@Allowed,
			@Setting,
			@EventID,
			@EventDescription

	RETURN @ID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[GeneralSecurityEventSchema]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[GeneralSecurityEventSchema]
GO
CREATE PROCEDURE [dbo].[GeneralSecurityEventSchema]
AS
	SELECT
	'IF OBJECT_ID(''tempdb..#GeneralSecurityEvent'') IS NULL' + CAST(0x0A AS CHAR(1)) +
	'	CREATE TABLE #GeneralSecurityEvent (' + CAST(0x0A AS CHAR(1)) +
	'		GeneralSecurityEventID	int NULL,' + CAST(0x0A AS CHAR(1)) +
	'		ComputerID		int NOT NULL,' + CAST(0x0A AS CHAR(1)) +
	'		UserID			int NOT NULL,' + CAST(0x0A AS CHAR(1)) +
	'		[DateTime]		datetime NOT NULL,' + CAST(0x0A AS CHAR(1)) +
	'		Allowed			bit NULL,' + CAST(0x0A AS CHAR(1)) +
	'		Setting			nvarchar(128) COLLATE database_default NOT NULL,' + CAST(0x0A AS CHAR(1)) +
	'		EventID			int NOT NULL,' + CAST(0x0A AS CHAR(1)) +
	'		EventDescription	nvarchar(256) COLLATE database_default NOT NULL' + CAST(0x0A AS CHAR(1)) +
	'	)' + CAST(0x0A AS CHAR(1)) +
	'ELSE' + CAST(0x0A AS CHAR(1)) +
	'	DELETE FROM #GeneralSecurityEvent' + CAST(0x0A AS CHAR(1)) +
	'' AS SQL
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[GeneralSecurityEventTempAdd]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[GeneralSecurityEventTempAdd]
GO
CREATE PROCEDURE dbo.[GeneralSecurityEventTempAdd]
	@GeneralSecurityEventID	int,
	@ComputerID		int,
	@UserID			int,
	@DateTime		datetime,
	@Allowed		bit = NULL,
	@Setting		nvarchar(128),
	@EventID		int,
	@EventDescription	nvarchar(256)
AS
	INSERT INTO #GeneralSecurityEvent (
		GeneralSecurityEventID,
		ComputerID,
		UserID,
		[DateTime],
		Allowed,
		Setting,
		EventID,
		EventDescription
	)
	VALUES (
		@GeneralSecurityEventID,
		@ComputerID,
		@UserID,
		@DateTime,
		@Allowed,
		@Setting,
		@EventID,
		@EventDescription
	)
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[GeneralSecurityEventAddBatch]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[GeneralSecurityEventAddBatch]
GO
CREATE PROCEDURE dbo.[GeneralSecurityEventAddBatch]
AS
	DECLARE @count int
	INSERT dbo.GeneralSecurityEvent (
		ComputerID,
		UserID,
		[DateTime],
		Allowed,
		Setting,
		EventID,
		EventDescription
	)
		SELECT	ComputerID,
			UserID,
			[DateTime],
			Allowed,
			Setting,
			EventID,
			EventDescription
		FROM #GeneralSecurityEvent
	SET @count = @@ROWCOUNT
	DROP TABLE #GeneralSecurityEvent	-- Drop temporary table
	RETURN @count
GO

/*
Add new GeneralSecurityEvent bound to
	User using UserOUID, UserCN
	with ComputerID, DateTime, Allowed, Setting, EventID, EventDescription
*/

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[GeneralSecurityEventUpdateByID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[GeneralSecurityEventUpdateByID]
GO
CREATE PROCEDURE [dbo].[GeneralSecurityEventUpdateByID]
	@GeneralSecurityEventID	int,
	@ComputerID		int,
	@UserID			int,
	@DateTime		datetime,
	@Allowed		bit = NULL,
	@Setting		nvarchar(128),
	@EventID		int,
	@EventDescription	nvarchar(256)
AS
	DECLARE	@ID	int
	SET @ID = 0

	UPDATE	[dbo].[GeneralSecurityEvent]
	SET	@ID = GeneralSecurityEventID,
		ComputerID = @ComputerID,
		UserID = @UserID,
		[DateTime] = @DateTime,
		Allowed = @Allowed,
		Setting = @Setting,
		EventID = @EventID,
		EventDescription = @EventDescription
	WHERE	GeneralSecurityEventID = @GeneralSecurityEventID
	RETURN @ID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[GeneralSecurityEventUpdateBatchByID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[GeneralSecurityEventUpdateBatchByID]
GO
CREATE PROCEDURE dbo.[GeneralSecurityEventUpdateBatchByID]
AS
	DECLARE @count int

	CREATE INDEX [TempGeneralSecurityEventID]
		ON #GeneralSecurityEvent (GeneralSecurityEventID)

	UPDATE	[dbo].[GeneralSecurityEvent]
	SET	ComputerID = t.ComputerID,
		UserID = t.UserID,
		[DateTime] = t.[DateTime],
		Allowed = t.Allowed,
		Setting = t.Setting,
		EventID = t.EventID,
		EventDescription = t.EventDescription
	FROM	#GeneralSecurityEvent AS t
	WHERE	GeneralSecurityEvent.GeneralSecurityEventID = t.GeneralSecurityEventID
	SET @count = @@ROWCOUNT
	DROP TABLE #GeneralSecurityEvent	-- Drop the temporary table
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[GeneralSecurityEventUpdateByComputerIDUserIDDateTimeEventID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[GeneralSecurityEventUpdateByComputerIDUserIDDateTimeEventID]
GO
CREATE PROCEDURE [dbo].[GeneralSecurityEventUpdateByComputerIDUserIDDateTimeEventID]
	@ComputerID		int,
	@UserID			int,
	@DateTime		datetime,
	@EventID		int,
	@Allowed		bit = NULL,
	@Setting		nvarchar(128),
	@EventDescription	nvarchar(256)
AS
	DECLARE	@ID	int
	SET @ID = 0

	UPDATE	[dbo].[GeneralSecurityEvent]
	SET	@ID = GeneralSecurityEventID,
		Allowed = @Allowed,
		Setting = @Setting,
		EventDescription = @EventDescription
	WHERE	ComputerID = @ComputerID
	  AND	UserID = @UserID
	  AND	[DateTime] = @DateTime
	  AND	EventID = @EventID
	RETURN @ID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[GeneralSecurityEventUpdateBatchByComputerIDUserIDDateTimeEventID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[GeneralSecurityEventUpdateBatchByComputerIDUserIDDateTimeEventID]
GO
CREATE PROCEDURE dbo.[GeneralSecurityEventUpdateBatchByComputerIDUserIDDateTimeEventID]
AS
	DECLARE @count int

	CREATE INDEX [TempGeneralSecurityEventComputerIDUserIDDateTimeEventID]
		ON #GeneralSecurityEvent (ComputerID, UserID, [DateTime], EventID)

	UPDATE	[dbo].[GeneralSecurityEvent]
	SET	Allowed = t.Allowed,
		Setting = t.Setting,
		EventDescription = t.EventDescription
	FROM	#GeneralSecurityEvent AS t
	WHERE	GeneralSecurityEvent.ComputerID = t.ComputerID
	  AND	GeneralSecurityEvent.UserID = t.UserID
	  AND	GeneralSecurityEvent.[DateTime] = t.[DateTime]
	  AND	GeneralSecurityEvent.EventID = t.EventID
	SET @count = @@ROWCOUNT
	DROP TABLE #GeneralSecurityEvent	-- Drop the temporary table
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[GeneralSecurityEventPutByComputerIDUserIDDateTimeEventID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[GeneralSecurityEventPutByComputerIDUserIDDateTimeEventID]
GO
CREATE PROCEDURE [dbo].[GeneralSecurityEventPutByComputerIDUserIDDateTimeEventID]
	@ComputerID		int,
	@UserID			int,
	@DateTime		datetime,
	@EventID		int,
	@Allowed		bit = NULL,
	@Setting		nvarchar(128),
	@EventDescription	nvarchar(256)
AS
	DECLARE @ID	int

	SELECT	@ID = GeneralSecurityEventID
	FROM	GeneralSecurityEvent
	WHERE	ComputerID = @ComputerID
	  AND	UserID = @UserID
	  AND	[DateTime] = @DateTime
	  AND	EventID = @EventID

	IF @ID IS NULL
		EXEC @ID = GeneralSecurityEventAdd @ComputerID,
			@UserID,
			@DateTime,
			@Allowed,
			@Setting,
			@EventID,
			@EventDescription
	ELSE
		EXEC GeneralSecurityEventUpdateByComputerIDUserIDDateTimeEventID @ComputerID,
			@UserID,
			@DateTime,
			@EventID,
			@Allowed,
			@Setting,
			@EventDescription

	RETURN @ID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[GeneralSecurityEventPutBatchByComputerIDUserIDDateTimeEventID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[GeneralSecurityEventPutBatchByComputerIDUserIDDateTimeEventID]
GO
CREATE PROCEDURE [dbo].[GeneralSecurityEventPutBatchByComputerIDUserIDDateTimeEventID]
AS
	DECLARE @count AS int
	SET @count = 0

	CREATE INDEX [TempGeneralSecurityEventComputerIDUserIDDateTimeEventID]
		ON #GeneralSecurityEvent (ComputerID, UserID, [DateTime], EventID)

	BEGIN TRANSACTION
	UPDATE [dbo].[GeneralSecurityEvent]
		SET	Allowed = t.Allowed,
			Setting = t.Setting,
			EventDescription = t.EventDescription
		FROM	#GeneralSecurityEvent AS t
		WHERE	GeneralSecurityEvent.ComputerID = t.ComputerID
		  AND	GeneralSecurityEvent.UserID = t.UserID
		  AND	GeneralSecurityEvent.[DateTime] = t.[DateTime]
		  AND	GeneralSecurityEvent.EventID = t.EventID
	SET @count = @@ROWCOUNT

	INSERT [dbo].[GeneralSecurityEvent] (
		ComputerID,
		UserID,
		[DateTime],
		Allowed,
		Setting,
		EventID,
		EventDescription
	)
		SELECT	ComputerID,
			UserID,
			[DateTime],
			Allowed,
			Setting,
			EventID,
			EventDescription
		FROM	#GeneralSecurityEvent AS t
		WHERE NOT EXISTS(	-- Current record doesn't exist
			SELECT * FROM [dbo].[GeneralSecurityEvent]
			WHERE	GeneralSecurityEvent.ComputerID = t.ComputerID
			  AND	GeneralSecurityEvent.UserID = t.UserID
			  AND	GeneralSecurityEvent.[DateTime] = t.[DateTime]
			  AND	GeneralSecurityEvent.EventID = t.EventID
		)
	SET @count = @count + @@ROWCOUNT
	DROP TABLE #GeneralSecurityEvent	-- Drop the temporary table
	COMMIT WORK
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[GeneralSecurityEventRemoveBatch]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[GeneralSecurityEventRemoveBatch]
GO

CREATE PROCEDURE [dbo].[GeneralSecurityEventRemoveBatch]
AS

	CREATE INDEX [TempGeneralSecurityEventGeneralSecurityEventRemoveBatch]
		ON #GeneralSecurityEvent (GeneralSecurityEventID)	

	-- Delete records from GeneralSecurityEvent identified by fields of [TempGeneralSecurityEventGeneralSecurityEventRemoveBatch]
	DELETE [dbo].[GeneralSecurityEvent]
	WHERE EXISTS(
			SELECT * FROM #GeneralSecurityEvent AS t
			WHERE	GeneralSecurityEvent.GeneralSecurityEventID = t.GeneralSecurityEventID
		)
	DROP TABLE #GeneralSecurityEvent      -- Drop the temporary table
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[GeneralSecurityEventRemoveByID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[GeneralSecurityEventRemoveByID]
GO
CREATE PROCEDURE [dbo].[GeneralSecurityEventRemoveByID]
	@GeneralSecurityEventID	int
AS
	DELETE	[dbo].[GeneralSecurityEvent]
	WHERE	GeneralSecurityEventID = @GeneralSecurityEventID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[GeneralSecurityEventRemoveAll]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[GeneralSecurityEventRemoveAll]
GO
CREATE PROCEDURE [dbo].[GeneralSecurityEventRemoveAll]
	
AS
	DELETE	[dbo].[GeneralSecurityEvent]
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[WakeOnLANTaskGetByTaskUID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[WakeOnLANTaskGetByTaskUID]
GO
CREATE PROCEDURE [dbo].[WakeOnLANTaskGetByTaskUID]
	@TaskUID		binary(16)
AS
	SELECT	TaskUID,
		FriendlyName,
		StartTime
	FROM	[dbo].[WakeOnLANTask]
	WHERE	TaskUID = @TaskUID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[WakeOnLANTaskGetAll]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[WakeOnLANTaskGetAll]
GO
CREATE PROCEDURE [dbo].[WakeOnLANTaskGetAll]
AS
	SELECT	TaskUID,
		FriendlyName,
		StartTime
	FROM	[dbo].[WakeOnLANTask]
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[WakeOnLANTaskAdd]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[WakeOnLANTaskAdd]
GO
CREATE PROCEDURE [dbo].[WakeOnLANTaskAdd]
	@TaskUID		binary(16),
	@FriendlyName		nvarchar(400),
	@StartTime		datetime = NULL
AS
	INSERT INTO  dbo.WakeOnLANTask (
		TaskUID,
		FriendlyName,
		StartTime
	)
	VALUES (
		@TaskUID,
		@FriendlyName,
		@StartTime
	)
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[WakeOnLANTaskSchema]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[WakeOnLANTaskSchema]
GO
CREATE PROCEDURE [dbo].[WakeOnLANTaskSchema]
AS
	SELECT
	'IF OBJECT_ID(''tempdb..#WakeOnLANTask'') IS NULL' + CAST(0x0A AS CHAR(1)) +
	'	CREATE TABLE #WakeOnLANTask (' + CAST(0x0A AS CHAR(1)) +
	'		TaskUID			binary(16) NOT NULL,' + CAST(0x0A AS CHAR(1)) +
	'		FriendlyName		nvarchar(400) COLLATE database_default NOT NULL,' + CAST(0x0A AS CHAR(1)) +
	'		StartTime		datetime NULL' + CAST(0x0A AS CHAR(1)) +
	'	)' + CAST(0x0A AS CHAR(1)) +
	'ELSE' + CAST(0x0A AS CHAR(1)) +
	'	DELETE FROM #WakeOnLANTask' + CAST(0x0A AS CHAR(1)) +
	'' AS SQL
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[WakeOnLANTaskTempAdd]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[WakeOnLANTaskTempAdd]
GO
CREATE PROCEDURE dbo.[WakeOnLANTaskTempAdd]
	@TaskUID		binary(16),
	@FriendlyName		nvarchar(400),
	@StartTime		datetime = NULL
AS
	INSERT INTO #WakeOnLANTask (
		TaskUID,
		FriendlyName,
		StartTime
	)
	VALUES (
		@TaskUID,
		@FriendlyName,
		@StartTime
	)
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[WakeOnLANTaskAddBatch]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[WakeOnLANTaskAddBatch]
GO
CREATE PROCEDURE dbo.[WakeOnLANTaskAddBatch]
AS
	DECLARE @count int
	INSERT dbo.WakeOnLANTask (
		TaskUID,
		FriendlyName,
		StartTime
	)
		SELECT	TaskUID,
			FriendlyName,
			StartTime
		FROM #WakeOnLANTask
	SET @count = @@ROWCOUNT
	DROP TABLE #WakeOnLANTask	-- Drop temporary table
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[WakeOnLANTaskUpdateByTaskUID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[WakeOnLANTaskUpdateByTaskUID]
GO
CREATE PROCEDURE [dbo].[WakeOnLANTaskUpdateByTaskUID]
	@TaskUID		binary(16),
	@FriendlyName		nvarchar(400),
	@StartTime		datetime = NULL
AS
	UPDATE	[dbo].[WakeOnLANTask]
	SET	FriendlyName = @FriendlyName,
		StartTime = @StartTime
	WHERE	TaskUID = @TaskUID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[WakeOnLANTaskUpdateBatchByTaskUID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[WakeOnLANTaskUpdateBatchByTaskUID]
GO
CREATE PROCEDURE dbo.[WakeOnLANTaskUpdateBatchByTaskUID]
AS
	DECLARE @count int

	CREATE INDEX [TempWakeOnLANTaskTaskUID]
		ON #WakeOnLANTask (TaskUID)

	UPDATE	[dbo].[WakeOnLANTask]
	SET	FriendlyName = t.FriendlyName,
		StartTime = t.StartTime
	FROM	#WakeOnLANTask AS t
	WHERE	WakeOnLANTask.TaskUID = t.TaskUID
	SET @count = @@ROWCOUNT
	DROP TABLE #WakeOnLANTask	-- Drop the temporary table
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[WakeOnLANTaskPutByTaskUID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[WakeOnLANTaskPutByTaskUID]
GO
CREATE PROCEDURE [dbo].[WakeOnLANTaskPutByTaskUID]
	@TaskUID		binary(16),
	@FriendlyName		nvarchar(400),
	@StartTime		datetime = NULL
AS
	IF NOT EXISTS(
		SELECT	1
		FROM	dbo.WakeOnLANTask
		WHERE	TaskUID = @TaskUID
	)
		EXEC WakeOnLANTaskAdd @TaskUID,
			@FriendlyName,
			@StartTime
	ELSE
		EXEC WakeOnLANTaskUpdateByTaskUID @TaskUID,
			@FriendlyName,
			@StartTime
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[WakeOnLANTaskPutBatchByTaskUID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[WakeOnLANTaskPutBatchByTaskUID]
GO
CREATE PROCEDURE [dbo].[WakeOnLANTaskPutBatchByTaskUID]
AS
	DECLARE @count AS int
	SET @count = 0

	CREATE INDEX [TempWakeOnLANTaskTaskUID]
		ON #WakeOnLANTask (TaskUID)

	BEGIN TRANSACTION
	UPDATE [dbo].[WakeOnLANTask]
		SET	FriendlyName = t.FriendlyName,
			StartTime = t.StartTime
		FROM	#WakeOnLANTask AS t
		WHERE	WakeOnLANTask.TaskUID = t.TaskUID
	SET @count = @@ROWCOUNT

	INSERT [dbo].[WakeOnLANTask] (
		TaskUID,
		FriendlyName,
		StartTime
	)
		SELECT	TaskUID,
			FriendlyName,
			StartTime
		FROM	#WakeOnLANTask AS t
		WHERE NOT EXISTS(	-- Current record doesn't exist
			SELECT * FROM [dbo].[WakeOnLANTask]
			WHERE	WakeOnLANTask.TaskUID = t.TaskUID
		)
	SET @count = @count + @@ROWCOUNT
	DROP TABLE #WakeOnLANTask	-- Drop the temporary table
	COMMIT WORK
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[WakeOnLANTaskRemoveBatch]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[WakeOnLANTaskRemoveBatch]
GO

CREATE PROCEDURE [dbo].[WakeOnLANTaskRemoveBatch]
AS

	CREATE INDEX [TempWakeOnLANTaskWakeOnLANTaskRemoveBatch]
		ON #WakeOnLANTask (TaskUID)	

	-- Delete records from WakeOnLANTask identified by fields of [TempWakeOnLANTaskWakeOnLANTaskRemoveBatch]
	DELETE [dbo].[WakeOnLANTask]
	WHERE EXISTS(
			SELECT * FROM #WakeOnLANTask AS t
			WHERE	WakeOnLANTask.TaskUID = t.TaskUID
		)
	DROP TABLE #WakeOnLANTask      -- Drop the temporary table
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[WakeOnLANTaskRemoveByTaskUID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[WakeOnLANTaskRemoveByTaskUID]
GO
CREATE PROCEDURE [dbo].[WakeOnLANTaskRemoveByTaskUID]
	@TaskUID		binary(16)
AS
	-- WakeOnLANTask deletes cascade to:
	--	WakeOnLANDistributionJob by FK_WOLDistJob_Task
	--		WakeOnLANStatus by FK_WOLStatus_DistJob
	DELETE	[dbo].[WakeOnLANTask]
	WHERE	TaskUID = @TaskUID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[WakeOnLANTaskRemoveAll]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[WakeOnLANTaskRemoveAll]
GO
CREATE PROCEDURE [dbo].[WakeOnLANTaskRemoveAll]
	
AS
	DELETE	[dbo].[WakeOnLANTask]
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[WakeOnLANDistributionJobGetByDistJobUID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[WakeOnLANDistributionJobGetByDistJobUID]
GO
CREATE PROCEDURE [dbo].[WakeOnLANDistributionJobGetByDistJobUID]
	@DistJobUID		binary(16)
AS
	SELECT	DistJobUID,
		TaskUID,
		ServerUID,
		State
	FROM	[dbo].[WakeOnLANDistributionJob]
	WHERE	DistJobUID = @DistJobUID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[WakeOnLANDistributionJobGetAll]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[WakeOnLANDistributionJobGetAll]
GO
CREATE PROCEDURE [dbo].[WakeOnLANDistributionJobGetAll]
AS
	SELECT	DistJobUID,
		TaskUID,
		ServerUID,
		State
	FROM	[dbo].[WakeOnLANDistributionJob]
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[WakeOnLANDistributionJobAdd]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[WakeOnLANDistributionJobAdd]
GO
CREATE PROCEDURE [dbo].[WakeOnLANDistributionJobAdd]
	@DistJobUID		binary(16),
	@TaskUID		binary(16),
	@ServerUID		binary(16),
	@State			varchar(16)
AS
	INSERT INTO  dbo.WakeOnLANDistributionJob (
		DistJobUID,
		TaskUID,
		ServerUID,
		State
	)
	VALUES (
		@DistJobUID,
		@TaskUID,
		@ServerUID,
		@State
	)
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[WakeOnLANDistributionJobSchema]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[WakeOnLANDistributionJobSchema]
GO
CREATE PROCEDURE [dbo].[WakeOnLANDistributionJobSchema]
AS
	SELECT
	'IF OBJECT_ID(''tempdb..#WakeOnLANDistributionJob'') IS NULL' + CAST(0x0A AS CHAR(1)) +
	'	CREATE TABLE #WakeOnLANDistributionJob (' + CAST(0x0A AS CHAR(1)) +
	'		DistJobUID		binary(16) NOT NULL,' + CAST(0x0A AS CHAR(1)) +
	'		TaskUID			binary(16) NOT NULL,' + CAST(0x0A AS CHAR(1)) +
	'		ServerUID		binary(16) NOT NULL,' + CAST(0x0A AS CHAR(1)) +
	'		State			varchar(16) COLLATE database_default NOT NULL' + CAST(0x0A AS CHAR(1)) +
	'	)' + CAST(0x0A AS CHAR(1)) +
	'ELSE' + CAST(0x0A AS CHAR(1)) +
	'	DELETE FROM #WakeOnLANDistributionJob' + CAST(0x0A AS CHAR(1)) +
	'' AS SQL
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[WakeOnLANDistributionJobTempAdd]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[WakeOnLANDistributionJobTempAdd]
GO
CREATE PROCEDURE dbo.[WakeOnLANDistributionJobTempAdd]
	@DistJobUID		binary(16),
	@TaskUID		binary(16),
	@ServerUID		binary(16),
	@State			varchar(16)
AS
	INSERT INTO #WakeOnLANDistributionJob (
		DistJobUID,
		TaskUID,
		ServerUID,
		State
	)
	VALUES (
		@DistJobUID,
		@TaskUID,
		@ServerUID,
		@State
	)
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[WakeOnLANDistributionJobAddBatch]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[WakeOnLANDistributionJobAddBatch]
GO
CREATE PROCEDURE dbo.[WakeOnLANDistributionJobAddBatch]
AS
	DECLARE @count int
	INSERT dbo.WakeOnLANDistributionJob (
		DistJobUID,
		TaskUID,
		ServerUID,
		State
	)
		SELECT	DistJobUID,
			TaskUID,
			ServerUID,
			State
		FROM #WakeOnLANDistributionJob
	SET @count = @@ROWCOUNT
	DROP TABLE #WakeOnLANDistributionJob	-- Drop temporary table
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[WakeOnLANDistributionJobUpdateByDistJobUID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[WakeOnLANDistributionJobUpdateByDistJobUID]
GO
CREATE PROCEDURE [dbo].[WakeOnLANDistributionJobUpdateByDistJobUID]
	@DistJobUID		binary(16),
	@TaskUID		binary(16),
	@ServerUID		binary(16),
	@State			varchar(16)
AS
	UPDATE	[dbo].[WakeOnLANDistributionJob]
	SET	TaskUID = @TaskUID,
		ServerUID = @ServerUID,
		State = @State
	WHERE	DistJobUID = @DistJobUID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[WakeOnLANDistributionJobUpdateBatchByDistJobUID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[WakeOnLANDistributionJobUpdateBatchByDistJobUID]
GO
CREATE PROCEDURE dbo.[WakeOnLANDistributionJobUpdateBatchByDistJobUID]
AS
	DECLARE @count int

	CREATE INDEX [TempWakeOnLANDistributionJobDistJobUID]
		ON #WakeOnLANDistributionJob (DistJobUID)

	UPDATE	[dbo].[WakeOnLANDistributionJob]
	SET	TaskUID = t.TaskUID,
		ServerUID = t.ServerUID,
		State = t.State
	FROM	#WakeOnLANDistributionJob AS t
	WHERE	WakeOnLANDistributionJob.DistJobUID = t.DistJobUID
	SET @count = @@ROWCOUNT
	DROP TABLE #WakeOnLANDistributionJob	-- Drop the temporary table
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[WakeOnLANDistributionJobPutByDistJobUID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[WakeOnLANDistributionJobPutByDistJobUID]
GO
CREATE PROCEDURE [dbo].[WakeOnLANDistributionJobPutByDistJobUID]
	@DistJobUID		binary(16),
	@TaskUID		binary(16),
	@ServerUID		binary(16),
	@State			varchar(16)
AS
	IF NOT EXISTS(
		SELECT	1
		FROM	dbo.WakeOnLANDistributionJob
		WHERE	DistJobUID = @DistJobUID
	)
		EXEC WakeOnLANDistributionJobAdd @DistJobUID,
			@TaskUID,
			@ServerUID,
			@State
	ELSE
		EXEC WakeOnLANDistributionJobUpdateByDistJobUID @DistJobUID,
			@TaskUID,
			@ServerUID,
			@State
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[WakeOnLANDistributionJobPutBatchByDistJobUID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[WakeOnLANDistributionJobPutBatchByDistJobUID]
GO
CREATE PROCEDURE [dbo].[WakeOnLANDistributionJobPutBatchByDistJobUID]
AS
	DECLARE @count AS int
	SET @count = 0

	CREATE INDEX [TempWakeOnLANDistributionJobDistJobUID]
		ON #WakeOnLANDistributionJob (DistJobUID)

	BEGIN TRANSACTION
	UPDATE [dbo].[WakeOnLANDistributionJob]
		SET	TaskUID = t.TaskUID,
			ServerUID = t.ServerUID,
			State = t.State
		FROM	#WakeOnLANDistributionJob AS t
		WHERE	WakeOnLANDistributionJob.DistJobUID = t.DistJobUID
	SET @count = @@ROWCOUNT

	INSERT [dbo].[WakeOnLANDistributionJob] (
		DistJobUID,
		TaskUID,
		ServerUID,
		State
	)
		SELECT	DistJobUID,
			TaskUID,
			ServerUID,
			State
		FROM	#WakeOnLANDistributionJob AS t
		WHERE NOT EXISTS(	-- Current record doesn't exist
			SELECT * FROM [dbo].[WakeOnLANDistributionJob]
			WHERE	WakeOnLANDistributionJob.DistJobUID = t.DistJobUID
		)
	SET @count = @count + @@ROWCOUNT
	DROP TABLE #WakeOnLANDistributionJob	-- Drop the temporary table
	COMMIT WORK
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[WakeOnLANDistributionJobRemoveBatch]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[WakeOnLANDistributionJobRemoveBatch]
GO

CREATE PROCEDURE [dbo].[WakeOnLANDistributionJobRemoveBatch]
AS

	CREATE INDEX [TempWakeOnLANDistributionJobWakeOnLANDistributionJobRemoveBatch]
		ON #WakeOnLANDistributionJob (DistJobUID)	

	-- Delete records from WakeOnLANDistributionJob identified by fields of [TempWakeOnLANDistributionJobWakeOnLANDistributionJobRemoveBatch]
	DELETE [dbo].[WakeOnLANDistributionJob]
	WHERE EXISTS(
			SELECT * FROM #WakeOnLANDistributionJob AS t
			WHERE	WakeOnLANDistributionJob.DistJobUID = t.DistJobUID
		)
	DROP TABLE #WakeOnLANDistributionJob      -- Drop the temporary table
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[WakeOnLANDistributionJobRemoveByDistJobUID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[WakeOnLANDistributionJobRemoveByDistJobUID]
GO
CREATE PROCEDURE [dbo].[WakeOnLANDistributionJobRemoveByDistJobUID]
	@DistJobUID		binary(16)
AS
	-- WakeOnLANDistributionJob deletes cascade to:
	--	WakeOnLANStatus by FK_WOLStatus_DistJob
	DELETE	[dbo].[WakeOnLANDistributionJob]
	WHERE	DistJobUID = @DistJobUID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[WakeOnLANDistributionJobRemoveAll]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[WakeOnLANDistributionJobRemoveAll]
GO
CREATE PROCEDURE [dbo].[WakeOnLANDistributionJobRemoveAll]
	
AS
	DELETE	[dbo].[WakeOnLANDistributionJob]
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[WakeOnLANStatusGetByDistJobUIDComputerID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[WakeOnLANStatusGetByDistJobUIDComputerID]
GO
CREATE PROCEDURE [dbo].[WakeOnLANStatusGetByDistJobUIDComputerID]
	@DistJobUID		binary(16),
	@ComputerID		int
AS
	SELECT	DistJobUID,
		ComputerID,
		State
	FROM	[dbo].[WakeOnLANStatus]
	WHERE	DistJobUID = @DistJobUID
	  AND	ComputerID = @ComputerID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[WakeOnLANStatusGetAll]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[WakeOnLANStatusGetAll]
GO
CREATE PROCEDURE [dbo].[WakeOnLANStatusGetAll]
AS
	SELECT	DistJobUID,
		ComputerID,
		State
	FROM	[dbo].[WakeOnLANStatus]
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[WakeOnLANStatusAdd]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[WakeOnLANStatusAdd]
GO
CREATE PROCEDURE [dbo].[WakeOnLANStatusAdd]
	@DistJobUID		binary(16),
	@ComputerID		int,
	@State			varchar(16)
AS
	INSERT INTO  dbo.WakeOnLANStatus (
		DistJobUID,
		ComputerID,
		State
	)
	VALUES (
		@DistJobUID,
		@ComputerID,
		@State
	)
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[WakeOnLANStatusSchema]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[WakeOnLANStatusSchema]
GO
CREATE PROCEDURE [dbo].[WakeOnLANStatusSchema]
AS
	SELECT
	'IF OBJECT_ID(''tempdb..#WakeOnLANStatus'') IS NULL' + CAST(0x0A AS CHAR(1)) +
	'	CREATE TABLE #WakeOnLANStatus (' + CAST(0x0A AS CHAR(1)) +
	'		DistJobUID		binary(16) NOT NULL,' + CAST(0x0A AS CHAR(1)) +
	'		ComputerID		int NOT NULL,' + CAST(0x0A AS CHAR(1)) +
	'		State			varchar(16) COLLATE database_default NOT NULL' + CAST(0x0A AS CHAR(1)) +
	'	)' + CAST(0x0A AS CHAR(1)) +
	'ELSE' + CAST(0x0A AS CHAR(1)) +
	'	DELETE FROM #WakeOnLANStatus' + CAST(0x0A AS CHAR(1)) +
	'' AS SQL
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[WakeOnLANStatusTempAdd]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[WakeOnLANStatusTempAdd]
GO
CREATE PROCEDURE dbo.[WakeOnLANStatusTempAdd]
	@DistJobUID		binary(16),
	@ComputerID		int,
	@State			varchar(16)
AS
	INSERT INTO #WakeOnLANStatus (
		DistJobUID,
		ComputerID,
		State
	)
	VALUES (
		@DistJobUID,
		@ComputerID,
		@State
	)
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[WakeOnLANStatusAddBatch]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[WakeOnLANStatusAddBatch]
GO
CREATE PROCEDURE dbo.[WakeOnLANStatusAddBatch]
AS
	DECLARE @count int
	INSERT dbo.WakeOnLANStatus (
		DistJobUID,
		ComputerID,
		State
	)
		SELECT	DistJobUID,
			ComputerID,
			State
		FROM #WakeOnLANStatus
	SET @count = @@ROWCOUNT
	DROP TABLE #WakeOnLANStatus	-- Drop temporary table
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[WakeOnLANStatusUpdateByDistJobUIDComputerID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[WakeOnLANStatusUpdateByDistJobUIDComputerID]
GO
CREATE PROCEDURE [dbo].[WakeOnLANStatusUpdateByDistJobUIDComputerID]
	@DistJobUID		binary(16),
	@ComputerID		int,
	@State			varchar(16)
AS
	UPDATE	[dbo].[WakeOnLANStatus]
	SET	State = @State
	WHERE	DistJobUID = @DistJobUID
	  AND	ComputerID = @ComputerID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[WakeOnLANStatusUpdateBatchByDistJobUIDComputerID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[WakeOnLANStatusUpdateBatchByDistJobUIDComputerID]
GO
CREATE PROCEDURE dbo.[WakeOnLANStatusUpdateBatchByDistJobUIDComputerID]
AS
	DECLARE @count int

	CREATE INDEX [TempWakeOnLANStatusDistJobUIDComputerID]
		ON #WakeOnLANStatus (DistJobUID, ComputerID)

	UPDATE	[dbo].[WakeOnLANStatus]
	SET	State = t.State
	FROM	#WakeOnLANStatus AS t
	WHERE	WakeOnLANStatus.DistJobUID = t.DistJobUID
	  AND	WakeOnLANStatus.ComputerID = t.ComputerID
	SET @count = @@ROWCOUNT
	DROP TABLE #WakeOnLANStatus	-- Drop the temporary table
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[WakeOnLANStatusPutByDistJobUIDComputerID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[WakeOnLANStatusPutByDistJobUIDComputerID]
GO
CREATE PROCEDURE [dbo].[WakeOnLANStatusPutByDistJobUIDComputerID]
	@DistJobUID		binary(16),
	@ComputerID		int,
	@State			varchar(16)
AS
	IF NOT EXISTS(
		SELECT	1
		FROM	dbo.WakeOnLANStatus
		WHERE	DistJobUID = @DistJobUID
		  AND	ComputerID = @ComputerID
	)
		EXEC WakeOnLANStatusAdd @DistJobUID,
			@ComputerID,
			@State
	ELSE
		EXEC WakeOnLANStatusUpdateByDistJobUIDComputerID @DistJobUID,
			@ComputerID,
			@State
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[WakeOnLANStatusPutBatchByDistJobUIDComputerID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[WakeOnLANStatusPutBatchByDistJobUIDComputerID]
GO
CREATE PROCEDURE [dbo].[WakeOnLANStatusPutBatchByDistJobUIDComputerID]
AS
	DECLARE @count AS int
	SET @count = 0

	CREATE INDEX [TempWakeOnLANStatusDistJobUIDComputerID]
		ON #WakeOnLANStatus (DistJobUID, ComputerID)

	BEGIN TRANSACTION
	UPDATE [dbo].[WakeOnLANStatus]
		SET	State = t.State
		FROM	#WakeOnLANStatus AS t
		WHERE	WakeOnLANStatus.DistJobUID = t.DistJobUID
		  AND	WakeOnLANStatus.ComputerID = t.ComputerID
	SET @count = @@ROWCOUNT

	INSERT [dbo].[WakeOnLANStatus] (
		DistJobUID,
		ComputerID,
		State
	)
		SELECT	DistJobUID,
			ComputerID,
			State
		FROM	#WakeOnLANStatus AS t
		WHERE NOT EXISTS(	-- Current record doesn't exist
			SELECT * FROM [dbo].[WakeOnLANStatus]
			WHERE	WakeOnLANStatus.DistJobUID = t.DistJobUID
			  AND	WakeOnLANStatus.ComputerID = t.ComputerID
		)
	SET @count = @count + @@ROWCOUNT
	DROP TABLE #WakeOnLANStatus	-- Drop the temporary table
	COMMIT WORK
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[WakeOnLANStatusRemoveBatch]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[WakeOnLANStatusRemoveBatch]
GO

CREATE PROCEDURE [dbo].[WakeOnLANStatusRemoveBatch]
AS

	CREATE INDEX [TempWakeOnLANStatusWakeOnLANStatusRemoveBatch]
		ON #WakeOnLANStatus (DistJobUID, ComputerID)	

	-- Delete records from WakeOnLANStatus identified by fields of [TempWakeOnLANStatusWakeOnLANStatusRemoveBatch]
	DELETE [dbo].[WakeOnLANStatus]
	WHERE EXISTS(
			SELECT * FROM #WakeOnLANStatus AS t
			WHERE	WakeOnLANStatus.DistJobUID = t.DistJobUID
			  AND	WakeOnLANStatus.ComputerID = t.ComputerID
		)
	DROP TABLE #WakeOnLANStatus      -- Drop the temporary table
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[WakeOnLANStatusRemoveByDistJobUIDComputerID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[WakeOnLANStatusRemoveByDistJobUIDComputerID]
GO
CREATE PROCEDURE [dbo].[WakeOnLANStatusRemoveByDistJobUIDComputerID]
	@DistJobUID		binary(16),
	@ComputerID		int
AS
	DELETE	[dbo].[WakeOnLANStatus]
	WHERE	DistJobUID = @DistJobUID
	  AND	ComputerID = @ComputerID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[WakeOnLANStatusRemoveAll]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[WakeOnLANStatusRemoveAll]
GO
CREATE PROCEDURE [dbo].[WakeOnLANStatusRemoveAll]
	
AS
	DELETE	[dbo].[WakeOnLANStatus]
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[PartitionTypeGetByName]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[PartitionTypeGetByName]
GO
CREATE PROCEDURE [dbo].[PartitionTypeGetByName]
	@PartitionTypeName	nvarchar(32)
AS
	SELECT	PartitionTypeID,
		PartitionTypeName
	FROM	[dbo].[PartitionType]
	WHERE	PartitionTypeName = @PartitionTypeName
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[PartitionTypeGetByID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[PartitionTypeGetByID]
GO
CREATE PROCEDURE [dbo].[PartitionTypeGetByID]
	@PartitionTypeID	int
AS
	SELECT	PartitionTypeID,
		PartitionTypeName
	FROM	[dbo].[PartitionType]
	WHERE	PartitionTypeID = @PartitionTypeID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[PartitionTypeGetAll]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[PartitionTypeGetAll]
GO
CREATE PROCEDURE [dbo].[PartitionTypeGetAll]
AS
	SELECT	PartitionTypeID,
		PartitionTypeName
	FROM	[dbo].[PartitionType]
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[PartitionTypeBind]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[PartitionTypeBind]
GO
CREATE PROCEDURE [dbo].[PartitionTypeBind]
	@PartitionTypeName	nvarchar(32)
AS
	DECLARE	@ID	int

	SELECT	@ID = PartitionTypeID
	FROM	[dbo].[PartitionType]
	WHERE	PartitionTypeName = @PartitionTypeName

	RETURN @ID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ResourceGetByName]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ResourceGetByName]
GO
CREATE PROCEDURE [dbo].[ResourceGetByName]
	@ResourceName		nvarchar(16)
AS
	SELECT	ResourceID,
		ResourceName,
		PartitionTypeID
	FROM	[dbo].[Resource]
	WHERE	ResourceName = @ResourceName
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ResourceGetByID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ResourceGetByID]
GO
CREATE PROCEDURE [dbo].[ResourceGetByID]
	@ResourceID		int
AS
	SELECT	ResourceID,
		ResourceName,
		PartitionTypeID
	FROM	[dbo].[Resource]
	WHERE	ResourceID = @ResourceID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ResourceGetAll]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ResourceGetAll]
GO
CREATE PROCEDURE [dbo].[ResourceGetAll]
AS
	SELECT	ResourceID,
		ResourceName,
		PartitionTypeID
	FROM	[dbo].[Resource]
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ResourceBind]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ResourceBind]
GO
CREATE PROCEDURE [dbo].[ResourceBind]
	@ResourceName		nvarchar(16),
	@PartitionTypeID	int = NULL
AS
	DECLARE	@ID	int

	SELECT	@ID = ResourceID
	FROM	[dbo].[Resource]
	WHERE	ResourceName = @ResourceName

	RETURN @ID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ActionClassGetByName]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ActionClassGetByName]
GO
CREATE PROCEDURE [dbo].[ActionClassGetByName]
	@ActionClassName	nvarchar(16)
AS
	SELECT	ActionClassID,
		ActionClassName
	FROM	[dbo].[ActionClass]
	WHERE	ActionClassName = @ActionClassName
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ActionClassGetByID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ActionClassGetByID]
GO
CREATE PROCEDURE [dbo].[ActionClassGetByID]
	@ActionClassID		int
AS
	SELECT	ActionClassID,
		ActionClassName
	FROM	[dbo].[ActionClass]
	WHERE	ActionClassID = @ActionClassID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ActionClassGetAll]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ActionClassGetAll]
GO
CREATE PROCEDURE [dbo].[ActionClassGetAll]
AS
	SELECT	ActionClassID,
		ActionClassName
	FROM	[dbo].[ActionClass]
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[ActionClassBind]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[ActionClassBind]
GO
CREATE PROCEDURE [dbo].[ActionClassBind]
	@ActionClassName	nvarchar(16)
AS
	DECLARE	@ID	int

	SELECT	@ID = ActionClassID
	FROM	[dbo].[ActionClass]
	WHERE	ActionClassName = @ActionClassName

	RETURN @ID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[RightGetByID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[RightGetByID]
GO
CREATE PROCEDURE [dbo].[RightGetByID]
	@RightID		int
AS
	SELECT	RightID,
		GroupID,
		ResourceID,
		ActionClassID,
		Denied,
		Value
	FROM	[dbo].[Right]
	WHERE	RightID = @RightID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[RightGetByGroupIDResourceIDActionClassIDValue]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[RightGetByGroupIDResourceIDActionClassIDValue]
GO
CREATE PROCEDURE [dbo].[RightGetByGroupIDResourceIDActionClassIDValue]
	@GroupID		int,
	@ResourceID		int,
	@ActionClassID		int,
	@Value			int = NULL
AS
	SELECT	RightID,
		GroupID,
		ResourceID,
		ActionClassID,
		Denied,
		Value
	FROM	[dbo].[Right]
	WHERE	GroupID = @GroupID
	  AND	ResourceID = @ResourceID
	  AND	ActionClassID = @ActionClassID
	  AND	(Value = @Value OR (Value IS NULL AND @Value IS NULL))
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[RightGetAllByGroupIDResourceIDActionClassID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[RightGetAllByGroupIDResourceIDActionClassID]
GO
CREATE PROCEDURE [dbo].[RightGetAllByGroupIDResourceIDActionClassID]
	@GroupID		int,
	@ResourceID		int,
	@ActionClassID		int
AS
	SELECT	RightID,
		GroupID,
		ResourceID,
		ActionClassID,
		Denied,
		Value
	FROM	[dbo].[Right]
	WHERE	GroupID = @GroupID
	  AND	ResourceID = @ResourceID
	  AND	ActionClassID = @ActionClassID
	ORDER BY Value
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[RightGetAllByGroupIDResourceID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[RightGetAllByGroupIDResourceID]
GO
CREATE PROCEDURE [dbo].[RightGetAllByGroupIDResourceID]
	@GroupID		int,
	@ResourceID		int
AS
	SELECT	RightID,
		GroupID,
		ResourceID,
		ActionClassID,
		Denied,
		Value
	FROM	[dbo].[Right]
	WHERE	GroupID = @GroupID
	  AND	ResourceID = @ResourceID
	ORDER BY ActionClassID, Value
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[RightGetAllByGroupID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[RightGetAllByGroupID]
GO
CREATE PROCEDURE [dbo].[RightGetAllByGroupID]
	@GroupID		int
AS
	SELECT	RightID,
		GroupID,
		ResourceID,
		ActionClassID,
		Denied,
		Value
	FROM	[dbo].[Right]
	WHERE	GroupID = @GroupID
	ORDER BY ResourceID, ActionClassID, Value
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[RightGetAll]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[RightGetAll]
GO
CREATE PROCEDURE [dbo].[RightGetAll]
AS
	SELECT	RightID,
		GroupID,
		ResourceID,
		ActionClassID,
		Denied,
		Value
	FROM	[dbo].[Right]
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[RightAdd]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[RightAdd]
GO
CREATE PROCEDURE [dbo].[RightAdd]
	@GroupID		int,
	@ResourceID		int,
	@ActionClassID		int,
	@Denied			bit = 0,
	@Value			int = NULL
AS
	INSERT INTO  dbo.[Right] (
		GroupID,
		ResourceID,
		ActionClassID,
		Denied,
		Value
	)
	VALUES (
		@GroupID,
		@ResourceID,
		@ActionClassID,
		@Denied,
		@Value
	)
	RETURN SCOPE_IDENTITY()
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[RightBind]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[RightBind]
GO
CREATE PROCEDURE [dbo].[RightBind]
	@GroupID		int,
	@ResourceID		int,
	@ActionClassID		int,
	@Denied			bit = 0,
	@Value			int = NULL
AS
	DECLARE	@ID	int

	SELECT	@ID = RightID
	FROM	[dbo].[Right]
	WHERE	GroupID = @GroupID
	  AND	ResourceID = @ResourceID
	  AND	ActionClassID = @ActionClassID
	  AND	(Value = @Value OR (Value IS NULL AND @Value IS NULL))

	IF @ID IS NULL
		EXEC @ID = RightAdd @GroupID,
			@ResourceID,
			@ActionClassID,
			@Denied,
			@Value

	RETURN @ID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[RightSchema]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[RightSchema]
GO
CREATE PROCEDURE [dbo].[RightSchema]
AS
	SELECT
	'IF OBJECT_ID(''tempdb..#Right'') IS NULL' + CAST(0x0A AS CHAR(1)) +
	'	CREATE TABLE #Right (' + CAST(0x0A AS CHAR(1)) +
	'		RightID			int NULL,' + CAST(0x0A AS CHAR(1)) +
	'		GroupID			int NOT NULL,' + CAST(0x0A AS CHAR(1)) +
	'		ResourceID		int NOT NULL,' + CAST(0x0A AS CHAR(1)) +
	'		ActionClassID		int NOT NULL,' + CAST(0x0A AS CHAR(1)) +
	'		Denied			bit NOT NULL DEFAULT 0,' + CAST(0x0A AS CHAR(1)) +
	'		Value			int NULL' + CAST(0x0A AS CHAR(1)) +
	'	)' + CAST(0x0A AS CHAR(1)) +
	'ELSE' + CAST(0x0A AS CHAR(1)) +
	'	DELETE FROM #Right' + CAST(0x0A AS CHAR(1)) +
	'' AS SQL
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[RightTempAdd]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[RightTempAdd]
GO
CREATE PROCEDURE dbo.[RightTempAdd]
	@RightID		int,
	@GroupID		int,
	@ResourceID		int,
	@ActionClassID		int,
	@Denied			bit = 0,
	@Value			int = NULL
AS
	INSERT INTO #Right (
		RightID,
		GroupID,
		ResourceID,
		ActionClassID,
		Denied,
		Value
	)
	VALUES (
		@RightID,
		@GroupID,
		@ResourceID,
		@ActionClassID,
		@Denied,
		@Value
	)
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[RightAddBatch]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[RightAddBatch]
GO
CREATE PROCEDURE dbo.[RightAddBatch]
AS
	DECLARE @count int
	INSERT dbo.[Right] (
		GroupID,
		ResourceID,
		ActionClassID,
		Denied,
		Value
	)
		SELECT	GroupID,
			ResourceID,
			ActionClassID,
			Denied,
			Value
		FROM #Right
	SET @count = @@ROWCOUNT
	DROP TABLE #Right	-- Drop temporary table
	RETURN @count
GO

/*
Add new Right bound to
	Resource using ResourceName
	ActionClass using ActionClassName
	Group using GUID with GroupOUID
	with Denied, Value
*/

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[RightUpdateByID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[RightUpdateByID]
GO
CREATE PROCEDURE [dbo].[RightUpdateByID]
	@RightID		int,
	@GroupID		int,
	@ResourceID		int,
	@ActionClassID		int,
	@Denied			bit = 0,
	@Value			int = NULL
AS
	DECLARE	@ID	int
	SET @ID = 0

	UPDATE	[dbo].[Right]
	SET	@ID = RightID,
		GroupID = @GroupID,
		ResourceID = @ResourceID,
		ActionClassID = @ActionClassID,
		Denied = @Denied,
		Value = @Value
	WHERE	RightID = @RightID
	RETURN @ID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[RightUpdateBatchByID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[RightUpdateBatchByID]
GO
CREATE PROCEDURE dbo.[RightUpdateBatchByID]
AS
	DECLARE @count int

	CREATE INDEX [TempRightID]
		ON #Right (RightID)

	UPDATE	[dbo].[Right]
	SET	GroupID = t.GroupID,
		ResourceID = t.ResourceID,
		ActionClassID = t.ActionClassID,
		Denied = t.Denied,
		Value = t.Value
	FROM	#Right AS t
	WHERE	[Right].RightID = t.RightID
	SET @count = @@ROWCOUNT
	DROP TABLE #Right	-- Drop the temporary table
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[RightUpdateByGroupIDResourceIDActionClassIDValue]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[RightUpdateByGroupIDResourceIDActionClassIDValue]
GO
CREATE PROCEDURE [dbo].[RightUpdateByGroupIDResourceIDActionClassIDValue]
	@GroupID		int,
	@ResourceID		int,
	@ActionClassID		int,
	@Value			int = NULL,
	@Denied			bit = 0
AS
	DECLARE	@ID	int
	SET @ID = 0

	UPDATE	[dbo].[Right]
	SET	@ID = RightID,
		Denied = @Denied
	WHERE	GroupID = @GroupID
	  AND	ResourceID = @ResourceID
	  AND	ActionClassID = @ActionClassID
	  AND	(Value = @Value OR (Value IS NULL AND @Value IS NULL))
	RETURN @ID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[RightUpdateBatchByGroupIDResourceIDActionClassIDValue]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[RightUpdateBatchByGroupIDResourceIDActionClassIDValue]
GO
CREATE PROCEDURE dbo.[RightUpdateBatchByGroupIDResourceIDActionClassIDValue]
AS
	DECLARE @count int

	CREATE INDEX [TempRightGroupIDResourceIDActionClassIDValue]
		ON #Right (GroupID, ResourceID, ActionClassID, Value)

	UPDATE	[dbo].[Right]
	SET	Denied = t.Denied
	FROM	#Right AS t
	WHERE	[Right].GroupID = t.GroupID
	  AND	[Right].ResourceID = t.ResourceID
	  AND	[Right].ActionClassID = t.ActionClassID
	  AND	([Right].Value = t.Value OR ([Right].Value IS NULL AND t.Value IS NULL))
	SET @count = @@ROWCOUNT
	DROP TABLE #Right	-- Drop the temporary table
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[RightPutByGroupIDResourceIDActionClassIDValue]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[RightPutByGroupIDResourceIDActionClassIDValue]
GO
CREATE PROCEDURE [dbo].[RightPutByGroupIDResourceIDActionClassIDValue]
	@GroupID		int,
	@ResourceID		int,
	@ActionClassID		int,
	@Value			int = NULL,
	@Denied			bit = 0
AS
	DECLARE @ID	int

	SELECT	@ID = RightID
	FROM	[Right]
	WHERE	GroupID = @GroupID
	  AND	ResourceID = @ResourceID
	  AND	ActionClassID = @ActionClassID
	  AND	(Value = @Value OR (Value IS NULL AND @Value IS NULL))

	IF @ID IS NULL
		EXEC @ID = RightAdd @GroupID,
			@ResourceID,
			@ActionClassID,
			@Denied,
			@Value
	ELSE
		EXEC RightUpdateByGroupIDResourceIDActionClassIDValue @GroupID,
			@ResourceID,
			@ActionClassID,
			@Value,
			@Denied

	RETURN @ID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[RightPutBatchByGroupIDResourceIDActionClassIDValue]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[RightPutBatchByGroupIDResourceIDActionClassIDValue]
GO
CREATE PROCEDURE [dbo].[RightPutBatchByGroupIDResourceIDActionClassIDValue]
AS
	DECLARE @count AS int
	SET @count = 0

	CREATE INDEX [TempRightGroupIDResourceIDActionClassIDValue]
		ON #Right (GroupID, ResourceID, ActionClassID, Value)

	BEGIN TRANSACTION
	UPDATE [dbo].[Right]
		SET	Denied = t.Denied
		FROM	#Right AS t
		WHERE	[Right].GroupID = t.GroupID
		  AND	[Right].ResourceID = t.ResourceID
		  AND	[Right].ActionClassID = t.ActionClassID
		  AND	([Right].Value = t.Value OR ([Right].Value IS NULL AND t.Value IS NULL))
	SET @count = @@ROWCOUNT

	INSERT [dbo].[Right] (
		GroupID,
		ResourceID,
		ActionClassID,
		Denied,
		Value
	)
		SELECT	GroupID,
			ResourceID,
			ActionClassID,
			Denied,
			Value
		FROM	#Right AS t
		WHERE NOT EXISTS(	-- Current record doesn't exist
			SELECT * FROM [dbo].[Right]
			WHERE	[Right].GroupID = t.GroupID
			  AND	[Right].ResourceID = t.ResourceID
			  AND	[Right].ActionClassID = t.ActionClassID
			  AND	([Right].Value = t.Value OR ([Right].Value IS NULL AND t.Value IS NULL))
		)
	SET @count = @count + @@ROWCOUNT
	DROP TABLE #Right	-- Drop the temporary table
	COMMIT WORK
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[RightRemoveBatch]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[RightRemoveBatch]
GO

CREATE PROCEDURE [dbo].[RightRemoveBatch]
AS

	CREATE INDEX [TempRightRightRemoveBatch]
		ON #Right (RightID)	

	-- Delete records from Right identified by fields of [TempRightRightRemoveBatch]
	DELETE [dbo].[Right]
	WHERE EXISTS(
			SELECT * FROM #Right AS t
			WHERE	[Right].RightID = t.RightID
		)
	DROP TABLE #Right      -- Drop the temporary table
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[RightRemoveByID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[RightRemoveByID]
GO
CREATE PROCEDURE [dbo].[RightRemoveByID]
	@RightID		int
AS
	DELETE	[dbo].[Right]
	WHERE	RightID = @RightID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[RightRemoveByGroupIDResourceIDActionClassIDValue]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[RightRemoveByGroupIDResourceIDActionClassIDValue]
GO
CREATE PROCEDURE [dbo].[RightRemoveByGroupIDResourceIDActionClassIDValue]
	@GroupID		int,
	@ResourceID		int,
	@ActionClassID		int,
	@Value			int = NULL
AS
	DELETE	[dbo].[Right]
	WHERE	GroupID = @GroupID
	  AND	ResourceID = @ResourceID
	  AND	ActionClassID = @ActionClassID
	  AND	(Value = @Value OR (Value IS NULL AND @Value IS NULL))
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[RightRemoveAllByGroupIDResourceIDActionClassID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[RightRemoveAllByGroupIDResourceIDActionClassID]
GO
CREATE PROCEDURE [dbo].[RightRemoveAllByGroupIDResourceIDActionClassID]
	@GroupID		int,
	@ResourceID		int,
	@ActionClassID		int
AS
	DELETE	[dbo].[Right]
	WHERE	GroupID = @GroupID
	  AND	ResourceID = @ResourceID
	  AND	ActionClassID = @ActionClassID
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[RightRemoveAllByGroupIDResourceID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[RightRemoveAllByGroupIDResourceID]
GO
CREATE PROCEDURE [dbo].[RightRemoveAllByGroupIDResourceID]
	@GroupID		int,
	@ResourceID		int
AS
	DELETE	[dbo].[Right]
	WHERE	GroupID = @GroupID
	  AND	ResourceID = @ResourceID
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[RightRemoveAllByGroupID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[RightRemoveAllByGroupID]
GO
CREATE PROCEDURE [dbo].[RightRemoveAllByGroupID]
	@GroupID		int
AS
	DELETE	[dbo].[Right]
	WHERE	GroupID = @GroupID
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[RightRemoveAll]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[RightRemoveAll]
GO
CREATE PROCEDURE [dbo].[RightRemoveAll]
	
AS
	DELETE	[dbo].[Right]
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[RightReplaceSubsetByGroupID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[RightReplaceSubsetByGroupID]
GO
-- Replace the record subset selected by (@GroupID)
-- using unique identifier (GroupID, ResourceID, ActionClassID, Value)
-- updating fields (Denied)
CREATE PROCEDURE [dbo].[RightReplaceSubsetByGroupID]
	@GroupID		int
AS
	DECLARE @count AS int
	SET @count = 0

	CREATE INDEX [TempRightByGroupID]
		ON #Right (GroupID, ResourceID, ActionClassID, Value)

	BEGIN TRANSACTION
	DELETE [Right]
		WHERE	GroupID = @GroupID
		AND NOT EXISTS(		-- Replacement record doesn't exist
			SELECT * FROM #Right AS t
			WHERE	[Right].GroupID = t.GroupID
			  AND	[Right].ResourceID = t.ResourceID
			  AND	[Right].ActionClassID = t.ActionClassID
			  AND	([Right].Value = t.Value OR ([Right].Value IS NULL AND t.Value IS NULL))
		)

	UPDATE [dbo].[Right]
		SET	Denied = t.Denied
		FROM	#Right AS t
		WHERE	[Right].GroupID = t.GroupID
		  AND	[Right].ResourceID = t.ResourceID
		  AND	[Right].ActionClassID = t.ActionClassID
		  AND	([Right].Value = t.Value OR ([Right].Value IS NULL AND t.Value IS NULL))
	SET @count = @@ROWCOUNT

	INSERT [Right] (
		GroupID,
		ResourceID,
		ActionClassID,
		Denied,
		Value
	)
		SELECT	GroupID,
			ResourceID,
			ActionClassID,
			Denied,
			Value
		FROM	#Right AS t
		WHERE NOT EXISTS(	-- Current record doesn't exist
			SELECT * FROM [Right]
			WHERE	[Right].GroupID = t.GroupID
			  AND	[Right].ResourceID = t.ResourceID
			  AND	[Right].ActionClassID = t.ActionClassID
			  AND	([Right].Value = t.Value OR ([Right].Value IS NULL AND t.Value IS NULL))
		)
	SET @count = @count + @@ROWCOUNT
	DROP TABLE #Right	-- Drop the temporary table
	COMMIT WORK
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[AgentStatusGetByDeviceIDAgentVersionReported]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[AgentStatusGetByDeviceIDAgentVersionReported]
GO
CREATE PROCEDURE [dbo].[AgentStatusGetByDeviceIDAgentVersionReported]
	@DeviceID		int,
	@Agent			nvarchar(32),
	@Version		nvarchar(32),
	@Reported		datetime
AS
	SELECT	DeviceID,
		Agent,
		Version,
		Reported,
		ResultCode
	FROM	[dbo].[AgentStatus]
	WHERE	DeviceID = @DeviceID
	  AND	Agent = @Agent
	  AND	Version = @Version
	  AND	Reported = @Reported
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[AgentStatusGetAllByDeviceIDAgentVersion]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[AgentStatusGetAllByDeviceIDAgentVersion]
GO
CREATE PROCEDURE [dbo].[AgentStatusGetAllByDeviceIDAgentVersion]
	@DeviceID		int,
	@Agent			nvarchar(32),
	@Version		nvarchar(32)
AS
	SELECT	DeviceID,
		Agent,
		Version,
		Reported,
		ResultCode
	FROM	[dbo].[AgentStatus]
	WHERE	DeviceID = @DeviceID
	  AND	Agent = @Agent
	  AND	Version = @Version
	ORDER BY Reported
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[AgentStatusGetAllByDeviceIDAgent]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[AgentStatusGetAllByDeviceIDAgent]
GO
CREATE PROCEDURE [dbo].[AgentStatusGetAllByDeviceIDAgent]
	@DeviceID		int,
	@Agent			nvarchar(32)
AS
	SELECT	DeviceID,
		Agent,
		Version,
		Reported,
		ResultCode
	FROM	[dbo].[AgentStatus]
	WHERE	DeviceID = @DeviceID
	  AND	Agent = @Agent
	ORDER BY Version, Reported
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[AgentStatusGetAllByDeviceID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[AgentStatusGetAllByDeviceID]
GO
CREATE PROCEDURE [dbo].[AgentStatusGetAllByDeviceID]
	@DeviceID		int
AS
	SELECT	DeviceID,
		Agent,
		Version,
		Reported,
		ResultCode
	FROM	[dbo].[AgentStatus]
	WHERE	DeviceID = @DeviceID
	ORDER BY Agent, Version, Reported
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[AgentStatusGetAll]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[AgentStatusGetAll]
GO
CREATE PROCEDURE [dbo].[AgentStatusGetAll]
AS
	SELECT	DeviceID,
		Agent,
		Version,
		Reported,
		ResultCode
	FROM	[dbo].[AgentStatus]
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[AgentStatusAdd]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[AgentStatusAdd]
GO
CREATE PROCEDURE [dbo].[AgentStatusAdd]
	@DeviceID		int,
	@Agent			nvarchar(32),
	@Version		nvarchar(32),
	@Reported		datetime,
	@ResultCode		bigint
AS
	INSERT INTO  dbo.AgentStatus (
		DeviceID,
		Agent,
		Version,
		Reported,
		ResultCode
	)
	VALUES (
		@DeviceID,
		@Agent,
		@Version,
		@Reported,
		@ResultCode
	)
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[AgentStatusSchema]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[AgentStatusSchema]
GO
CREATE PROCEDURE [dbo].[AgentStatusSchema]
AS
	SELECT
	'IF OBJECT_ID(''tempdb..#AgentStatus'') IS NULL' + CAST(0x0A AS CHAR(1)) +
	'	CREATE TABLE #AgentStatus (' + CAST(0x0A AS CHAR(1)) +
	'		DeviceID		int NOT NULL,' + CAST(0x0A AS CHAR(1)) +
	'		Agent			nvarchar(32) COLLATE database_default NOT NULL,' + CAST(0x0A AS CHAR(1)) +
	'		Version			nvarchar(32) COLLATE database_default NOT NULL,' + CAST(0x0A AS CHAR(1)) +
	'		Reported		datetime NOT NULL,' + CAST(0x0A AS CHAR(1)) +
	'		ResultCode		bigint NOT NULL' + CAST(0x0A AS CHAR(1)) +
	'	)' + CAST(0x0A AS CHAR(1)) +
	'ELSE' + CAST(0x0A AS CHAR(1)) +
	'	DELETE FROM #AgentStatus' + CAST(0x0A AS CHAR(1)) +
	'' AS SQL
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[AgentStatusTempAdd]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[AgentStatusTempAdd]
GO
CREATE PROCEDURE dbo.[AgentStatusTempAdd]
	@DeviceID		int,
	@Agent			nvarchar(32),
	@Version		nvarchar(32),
	@Reported		datetime,
	@ResultCode		bigint
AS
	INSERT INTO #AgentStatus (
		DeviceID,
		Agent,
		Version,
		Reported,
		ResultCode
	)
	VALUES (
		@DeviceID,
		@Agent,
		@Version,
		@Reported,
		@ResultCode
	)
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[AgentStatusAddBatch]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[AgentStatusAddBatch]
GO
CREATE PROCEDURE dbo.[AgentStatusAddBatch]
AS
	DECLARE @count int
	INSERT dbo.AgentStatus (
		DeviceID,
		Agent,
		Version,
		Reported,
		ResultCode
	)
		SELECT	DeviceID,
			Agent,
			Version,
			Reported,
			ResultCode
		FROM #AgentStatus
	SET @count = @@ROWCOUNT
	DROP TABLE #AgentStatus	-- Drop temporary table
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[AgentStatusUpdateByDeviceIDAgentVersionReported]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[AgentStatusUpdateByDeviceIDAgentVersionReported]
GO
CREATE PROCEDURE [dbo].[AgentStatusUpdateByDeviceIDAgentVersionReported]
	@DeviceID		int,
	@Agent			nvarchar(32),
	@Version		nvarchar(32),
	@Reported		datetime,
	@ResultCode		bigint
AS
	UPDATE	[dbo].[AgentStatus]
	SET	ResultCode = @ResultCode
	WHERE	DeviceID = @DeviceID
	  AND	Agent = @Agent
	  AND	Version = @Version
	  AND	Reported = @Reported
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[AgentStatusUpdateBatchByDeviceIDAgentVersionReported]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[AgentStatusUpdateBatchByDeviceIDAgentVersionReported]
GO
CREATE PROCEDURE dbo.[AgentStatusUpdateBatchByDeviceIDAgentVersionReported]
AS
	DECLARE @count int

	CREATE INDEX [TempAgentStatusDeviceIDAgentVersionReported]
		ON #AgentStatus (DeviceID, Agent, Version, Reported)

	UPDATE	[dbo].[AgentStatus]
	SET	ResultCode = t.ResultCode
	FROM	#AgentStatus AS t
	WHERE	AgentStatus.DeviceID = t.DeviceID
	  AND	AgentStatus.Agent = t.Agent
	  AND	AgentStatus.Version = t.Version
	  AND	AgentStatus.Reported = t.Reported
	SET @count = @@ROWCOUNT
	DROP TABLE #AgentStatus	-- Drop the temporary table
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[AgentStatusPutByDeviceIDAgentVersionReported]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[AgentStatusPutByDeviceIDAgentVersionReported]
GO
CREATE PROCEDURE [dbo].[AgentStatusPutByDeviceIDAgentVersionReported]
	@DeviceID		int,
	@Agent			nvarchar(32),
	@Version		nvarchar(32),
	@Reported		datetime,
	@ResultCode		bigint
AS
	IF NOT EXISTS(
		SELECT	1
		FROM	dbo.AgentStatus
		WHERE	DeviceID = @DeviceID
		  AND	Agent = @Agent
		  AND	Version = @Version
		  AND	Reported = @Reported
	)
		EXEC AgentStatusAdd @DeviceID,
			@Agent,
			@Version,
			@Reported,
			@ResultCode
	ELSE
		EXEC AgentStatusUpdateByDeviceIDAgentVersionReported @DeviceID,
			@Agent,
			@Version,
			@Reported,
			@ResultCode
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[AgentStatusPutBatchByDeviceIDAgentVersionReported]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[AgentStatusPutBatchByDeviceIDAgentVersionReported]
GO
CREATE PROCEDURE [dbo].[AgentStatusPutBatchByDeviceIDAgentVersionReported]
AS
	DECLARE @count AS int
	SET @count = 0

	CREATE INDEX [TempAgentStatusDeviceIDAgentVersionReported]
		ON #AgentStatus (DeviceID, Agent, Version, Reported)

	BEGIN TRANSACTION
	UPDATE [dbo].[AgentStatus]
		SET	ResultCode = t.ResultCode
		FROM	#AgentStatus AS t
		WHERE	AgentStatus.DeviceID = t.DeviceID
		  AND	AgentStatus.Agent = t.Agent
		  AND	AgentStatus.Version = t.Version
		  AND	AgentStatus.Reported = t.Reported
	SET @count = @@ROWCOUNT

	INSERT [dbo].[AgentStatus] (
		DeviceID,
		Agent,
		Version,
		Reported,
		ResultCode
	)
		SELECT	DeviceID,
			Agent,
			Version,
			Reported,
			ResultCode
		FROM	#AgentStatus AS t
		WHERE NOT EXISTS(	-- Current record doesn't exist
			SELECT * FROM [dbo].[AgentStatus]
			WHERE	AgentStatus.DeviceID = t.DeviceID
			  AND	AgentStatus.Agent = t.Agent
			  AND	AgentStatus.Version = t.Version
			  AND	AgentStatus.Reported = t.Reported
		)
	SET @count = @count + @@ROWCOUNT
	DROP TABLE #AgentStatus	-- Drop the temporary table
	COMMIT WORK
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[AgentStatusRemoveBatch]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[AgentStatusRemoveBatch]
GO

CREATE PROCEDURE [dbo].[AgentStatusRemoveBatch]
AS

	CREATE INDEX [TempAgentStatusAgentStatusRemoveBatch]
		ON #AgentStatus (DeviceID, Agent, Version, Reported)	

	-- Delete records from AgentStatus identified by fields of [TempAgentStatusAgentStatusRemoveBatch]
	DELETE [dbo].[AgentStatus]
	WHERE EXISTS(
			SELECT * FROM #AgentStatus AS t
			WHERE	AgentStatus.DeviceID = t.DeviceID
			  AND	AgentStatus.Agent = t.Agent
			  AND	AgentStatus.Version = t.Version
			  AND	AgentStatus.Reported = t.Reported
		)
	DROP TABLE #AgentStatus      -- Drop the temporary table
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[AgentStatusRemoveByDeviceIDAgentVersionReported]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[AgentStatusRemoveByDeviceIDAgentVersionReported]
GO
CREATE PROCEDURE [dbo].[AgentStatusRemoveByDeviceIDAgentVersionReported]
	@DeviceID		int,
	@Agent			nvarchar(32),
	@Version		nvarchar(32),
	@Reported		datetime
AS
	DELETE	[dbo].[AgentStatus]
	WHERE	DeviceID = @DeviceID
	  AND	Agent = @Agent
	  AND	Version = @Version
	  AND	Reported = @Reported
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[AgentStatusRemoveAllByDeviceID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[AgentStatusRemoveAllByDeviceID]
GO
CREATE PROCEDURE [dbo].[AgentStatusRemoveAllByDeviceID]
	@DeviceID		int
AS
	DELETE	[dbo].[AgentStatus]
	WHERE	DeviceID = @DeviceID
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[AgentStatusRemoveAll]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[AgentStatusRemoveAll]
GO
CREATE PROCEDURE [dbo].[AgentStatusRemoveAll]
	
AS
	DELETE	[dbo].[AgentStatus]
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[AgentStatusReplaceSubsetByDeviceID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[AgentStatusReplaceSubsetByDeviceID]
GO
-- Replace the record subset selected by (@DeviceID)
-- using unique identifier (DeviceID, Agent, Version, Reported)
-- updating fields (ResultCode)
CREATE PROCEDURE [dbo].[AgentStatusReplaceSubsetByDeviceID]
	@DeviceID		int
AS
	DECLARE @count AS int
	SET @count = 0

	CREATE INDEX [TempAgentStatusByDeviceID]
		ON #AgentStatus (DeviceID, Agent, Version, Reported)

	BEGIN TRANSACTION
	DELETE [AgentStatus]
		WHERE	DeviceID = @DeviceID
		AND NOT EXISTS(		-- Replacement record doesn't exist
			SELECT * FROM #AgentStatus AS t
			WHERE	AgentStatus.DeviceID = t.DeviceID
			  AND	AgentStatus.Agent = t.Agent
			  AND	AgentStatus.Version = t.Version
			  AND	AgentStatus.Reported = t.Reported
		)

	UPDATE [dbo].[AgentStatus]
		SET	ResultCode = t.ResultCode
		FROM	#AgentStatus AS t
		WHERE	AgentStatus.DeviceID = t.DeviceID
		  AND	AgentStatus.Agent = t.Agent
		  AND	AgentStatus.Version = t.Version
		  AND	AgentStatus.Reported = t.Reported
	SET @count = @@ROWCOUNT

	INSERT [AgentStatus] (
		DeviceID,
		Agent,
		Version,
		Reported,
		ResultCode
	)
		SELECT	DeviceID,
			Agent,
			Version,
			Reported,
			ResultCode
		FROM	#AgentStatus AS t
		WHERE NOT EXISTS(	-- Current record doesn't exist
			SELECT * FROM [AgentStatus]
			WHERE	AgentStatus.DeviceID = t.DeviceID
			  AND	AgentStatus.Agent = t.Agent
			  AND	AgentStatus.Version = t.Version
			  AND	AgentStatus.Reported = t.Reported
		)
	SET @count = @count + @@ROWCOUNT
	DROP TABLE #AgentStatus	-- Drop the temporary table
	COMMIT WORK
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[AMTEventLogGetByID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[AMTEventLogGetByID]
GO
CREATE PROCEDURE [dbo].[AMTEventLogGetByID]
	@AMTEventLogID		int
AS
	SELECT	AMTEventLogID,
		DeviceID,
		Reported,
		PETDeviceAddress,
		PETEventSensorType,
		PETEventType,
		PETEventOffset,
		PETEventSourceType,
		PETEventSeverity,
		PETSensorNumber,
		PETEntity,
		PETEntityInstance,
		PETEventData
	FROM	[dbo].[AMTEventLog]
	WHERE	AMTEventLogID = @AMTEventLogID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[AMTEventLogGetAllByDeviceID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[AMTEventLogGetAllByDeviceID]
GO
CREATE PROCEDURE [dbo].[AMTEventLogGetAllByDeviceID]
	@DeviceID		int
AS
	SELECT	AMTEventLogID,
		DeviceID,
		Reported,
		PETDeviceAddress,
		PETEventSensorType,
		PETEventType,
		PETEventOffset,
		PETEventSourceType,
		PETEventSeverity,
		PETSensorNumber,
		PETEntity,
		PETEntityInstance,
		PETEventData
	FROM	[dbo].[AMTEventLog]
	WHERE	DeviceID = @DeviceID
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[AMTEventLogGetAll]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[AMTEventLogGetAll]
GO
CREATE PROCEDURE [dbo].[AMTEventLogGetAll]
AS
	SELECT	AMTEventLogID,
		DeviceID,
		Reported,
		PETDeviceAddress,
		PETEventSensorType,
		PETEventType,
		PETEventOffset,
		PETEventSourceType,
		PETEventSeverity,
		PETSensorNumber,
		PETEntity,
		PETEntityInstance,
		PETEventData
	FROM	[dbo].[AMTEventLog]
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[AMTEventLogAdd]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[AMTEventLogAdd]
GO
CREATE PROCEDURE [dbo].[AMTEventLogAdd]
	@DeviceID		int,
	@Reported		datetime,
	@PETDeviceAddress	smallint,
	@PETEventSensorType	smallint,
	@PETEventType		smallint,
	@PETEventOffset		smallint,
	@PETEventSourceType	smallint,
	@PETEventSeverity	smallint,
	@PETSensorNumber	smallint,
	@PETEntity		smallint,
	@PETEntityInstance	smallint,
	@PETEventData		nvarchar(32)
AS
	INSERT INTO  dbo.AMTEventLog (
		DeviceID,
		Reported,
		PETDeviceAddress,
		PETEventSensorType,
		PETEventType,
		PETEventOffset,
		PETEventSourceType,
		PETEventSeverity,
		PETSensorNumber,
		PETEntity,
		PETEntityInstance,
		PETEventData
	)
	VALUES (
		@DeviceID,
		@Reported,
		@PETDeviceAddress,
		@PETEventSensorType,
		@PETEventType,
		@PETEventOffset,
		@PETEventSourceType,
		@PETEventSeverity,
		@PETSensorNumber,
		@PETEntity,
		@PETEntityInstance,
		@PETEventData
	)
	RETURN SCOPE_IDENTITY()
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[AMTEventLogSchema]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[AMTEventLogSchema]
GO
CREATE PROCEDURE [dbo].[AMTEventLogSchema]
AS
	SELECT
	'IF OBJECT_ID(''tempdb..#AMTEventLog'') IS NULL' + CAST(0x0A AS CHAR(1)) +
	'	CREATE TABLE #AMTEventLog (' + CAST(0x0A AS CHAR(1)) +
	'		AMTEventLogID		int NULL,' + CAST(0x0A AS CHAR(1)) +
	'		DeviceID		int NOT NULL,' + CAST(0x0A AS CHAR(1)) +
	'		Reported		datetime NOT NULL,' + CAST(0x0A AS CHAR(1)) +
	'		PETDeviceAddress	smallint NOT NULL,' + CAST(0x0A AS CHAR(1)) +
	'		PETEventSensorType	smallint NOT NULL,' + CAST(0x0A AS CHAR(1)) +
	'		PETEventType		smallint NOT NULL,' + CAST(0x0A AS CHAR(1)) +
	'		PETEventOffset		smallint NOT NULL,' + CAST(0x0A AS CHAR(1)) +
	'		PETEventSourceType	smallint NOT NULL,' + CAST(0x0A AS CHAR(1)) +
	'		PETEventSeverity	smallint NOT NULL,' + CAST(0x0A AS CHAR(1)) +
	'		PETSensorNumber		smallint NOT NULL,' + CAST(0x0A AS CHAR(1)) +
	'		PETEntity		smallint NOT NULL,' + CAST(0x0A AS CHAR(1)) +
	'		PETEntityInstance	smallint NOT NULL,' + CAST(0x0A AS CHAR(1)) +
	'		PETEventData		nvarchar(32) COLLATE database_default NOT NULL' + CAST(0x0A AS CHAR(1)) +
	'	)' + CAST(0x0A AS CHAR(1)) +
	'ELSE' + CAST(0x0A AS CHAR(1)) +
	'	DELETE FROM #AMTEventLog' + CAST(0x0A AS CHAR(1)) +
	'' AS SQL
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[AMTEventLogTempAdd]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[AMTEventLogTempAdd]
GO
CREATE PROCEDURE dbo.[AMTEventLogTempAdd]
	@AMTEventLogID		int,
	@DeviceID		int,
	@Reported		datetime,
	@PETDeviceAddress	smallint,
	@PETEventSensorType	smallint,
	@PETEventType		smallint,
	@PETEventOffset		smallint,
	@PETEventSourceType	smallint,
	@PETEventSeverity	smallint,
	@PETSensorNumber	smallint,
	@PETEntity		smallint,
	@PETEntityInstance	smallint,
	@PETEventData		nvarchar(32)
AS
	INSERT INTO #AMTEventLog (
		AMTEventLogID,
		DeviceID,
		Reported,
		PETDeviceAddress,
		PETEventSensorType,
		PETEventType,
		PETEventOffset,
		PETEventSourceType,
		PETEventSeverity,
		PETSensorNumber,
		PETEntity,
		PETEntityInstance,
		PETEventData
	)
	VALUES (
		@AMTEventLogID,
		@DeviceID,
		@Reported,
		@PETDeviceAddress,
		@PETEventSensorType,
		@PETEventType,
		@PETEventOffset,
		@PETEventSourceType,
		@PETEventSeverity,
		@PETSensorNumber,
		@PETEntity,
		@PETEntityInstance,
		@PETEventData
	)
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[AMTEventLogAddBatch]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[AMTEventLogAddBatch]
GO
CREATE PROCEDURE dbo.[AMTEventLogAddBatch]
AS
	DECLARE @count int
	INSERT dbo.AMTEventLog (
		DeviceID,
		Reported,
		PETDeviceAddress,
		PETEventSensorType,
		PETEventType,
		PETEventOffset,
		PETEventSourceType,
		PETEventSeverity,
		PETSensorNumber,
		PETEntity,
		PETEntityInstance,
		PETEventData
	)
		SELECT	DeviceID,
			Reported,
			PETDeviceAddress,
			PETEventSensorType,
			PETEventType,
			PETEventOffset,
			PETEventSourceType,
			PETEventSeverity,
			PETSensorNumber,
			PETEntity,
			PETEntityInstance,
			PETEventData
		FROM #AMTEventLog
	SET @count = @@ROWCOUNT
	DROP TABLE #AMTEventLog	-- Drop temporary table
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[AMTEventLogUpdateByID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[AMTEventLogUpdateByID]
GO
CREATE PROCEDURE [dbo].[AMTEventLogUpdateByID]
	@AMTEventLogID		int,
	@DeviceID		int,
	@Reported		datetime,
	@PETDeviceAddress	smallint,
	@PETEventSensorType	smallint,
	@PETEventType		smallint,
	@PETEventOffset		smallint,
	@PETEventSourceType	smallint,
	@PETEventSeverity	smallint,
	@PETSensorNumber	smallint,
	@PETEntity		smallint,
	@PETEntityInstance	smallint,
	@PETEventData		nvarchar(32)
AS
	DECLARE	@ID	int
	SET @ID = 0

	UPDATE	[dbo].[AMTEventLog]
	SET	@ID = AMTEventLogID,
		DeviceID = @DeviceID,
		Reported = @Reported,
		PETDeviceAddress = @PETDeviceAddress,
		PETEventSensorType = @PETEventSensorType,
		PETEventType = @PETEventType,
		PETEventOffset = @PETEventOffset,
		PETEventSourceType = @PETEventSourceType,
		PETEventSeverity = @PETEventSeverity,
		PETSensorNumber = @PETSensorNumber,
		PETEntity = @PETEntity,
		PETEntityInstance = @PETEntityInstance,
		PETEventData = @PETEventData
	WHERE	AMTEventLogID = @AMTEventLogID
	RETURN @ID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[AMTEventLogUpdateBatchByID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[AMTEventLogUpdateBatchByID]
GO
CREATE PROCEDURE dbo.[AMTEventLogUpdateBatchByID]
AS
	DECLARE @count int

	CREATE INDEX [TempAMTEventLogID]
		ON #AMTEventLog (AMTEventLogID)

	UPDATE	[dbo].[AMTEventLog]
	SET	DeviceID = t.DeviceID,
		Reported = t.Reported,
		PETDeviceAddress = t.PETDeviceAddress,
		PETEventSensorType = t.PETEventSensorType,
		PETEventType = t.PETEventType,
		PETEventOffset = t.PETEventOffset,
		PETEventSourceType = t.PETEventSourceType,
		PETEventSeverity = t.PETEventSeverity,
		PETSensorNumber = t.PETSensorNumber,
		PETEntity = t.PETEntity,
		PETEntityInstance = t.PETEntityInstance,
		PETEventData = t.PETEventData
	FROM	#AMTEventLog AS t
	WHERE	AMTEventLog.AMTEventLogID = t.AMTEventLogID
	SET @count = @@ROWCOUNT
	DROP TABLE #AMTEventLog	-- Drop the temporary table
	RETURN @count
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[AMTEventLogRemoveBatch]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[AMTEventLogRemoveBatch]
GO

CREATE PROCEDURE [dbo].[AMTEventLogRemoveBatch]
AS

	CREATE INDEX [TempAMTEventLogAMTEventLogRemoveBatch]
		ON #AMTEventLog (AMTEventLogID)	

	-- Delete records from AMTEventLog identified by fields of [TempAMTEventLogAMTEventLogRemoveBatch]
	DELETE [dbo].[AMTEventLog]
	WHERE EXISTS(
			SELECT * FROM #AMTEventLog AS t
			WHERE	AMTEventLog.AMTEventLogID = t.AMTEventLogID
		)
	DROP TABLE #AMTEventLog      -- Drop the temporary table
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[AMTEventLogRemoveByID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[AMTEventLogRemoveByID]
GO
CREATE PROCEDURE [dbo].[AMTEventLogRemoveByID]
	@AMTEventLogID		int
AS
	DELETE	[dbo].[AMTEventLog]
	WHERE	AMTEventLogID = @AMTEventLogID
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[AMTEventLogRemoveAllByDeviceID]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[AMTEventLogRemoveAllByDeviceID]
GO
CREATE PROCEDURE [dbo].[AMTEventLogRemoveAllByDeviceID]
	@DeviceID		int
AS
	DELETE	[dbo].[AMTEventLog]
	WHERE	DeviceID = @DeviceID
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_ID(N'[dbo].[AMTEventLogRemoveAll]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
	DROP PROCEDURE [dbo].[AMTEventLogRemoveAll]
GO
CREATE PROCEDURE [dbo].[AMTEventLogRemoveAll]
	
AS
	DELETE	[dbo].[AMTEventLog]
	RETURN @@ROWCOUNT
GO

/*
 * $Id: Directory.sql 99608 2011-04-29 01:40:39Z bwong $
 *
 * Procedures to use in database repair and reconciliation.
 *
 * Protected by US patent 6,006,034; patents pending.
 * Copyright 2000-2002 ManageSoft Corporation. All rights reserved.
 * Reproduction, adaptation, or translation without prior permission
 * is prohibited.
 */
-- USE ManageSoft
GO

PRINT 'Creating procedure to remove a domain'
IF EXISTS(SELECT * FROM sysobjects WHERE xtype = 'P'
        AND [name] = 'DomainRemove'
)
        DROP PROCEDURE DomainRemove
GO
CREATE PROCEDURE DomainRemove
	@OrganizationID int
AS
	BEGIN TRANSACTION
	
	DELETE FROM ADComputer WHERE DomainID = @OrganizationID
	DELETE FROM ADSDOU WHERE DomainID = @OrganizationID
	DELETE FROM ADUser WHERE DomainID = @OrganizationID
	DELETE FROM Policy WHERE DomainID = @OrganizationID
	DELETE FROM DomainConfiguration WHERE DomainID = @OrganizationID
	DELETE FROM NetworkLocation WHERE DomainID = @OrganizationID
	
	-- Duplicate NetworkDevices cannot be cascade deleted
	IF OBJECT_ID('tempdb..#DeletedNetworkDeviceID') IS NOT NULL
		DROP TABLE #DeletedNetworkDeviceID

	CREATE TABLE #DeletedNetworkDeviceID(DeviceID int)
       
	INSERT #DeletedNetworkDeviceID (DeviceID)
		SELECT DISTINCT DeviceID
		FROM NetworkDevice
			INNER JOIN Computer ON Computer.ComputerID = NetworkDevice.ComputerID
			INNER JOIN Organization ON Organization.OrganizationID = Computer.ComputerOUID
		WHERE Organization.DomainID = @OrganizationID
               
	DELETE FROM ActionApplies
	WHERE EXISTS (
		SELECT 1
		FROM #DeletedNetworkDeviceID
		WHERE #DeletedNetworkDeviceID.DeviceID = ActionApplies.DeviceID
	)

	UPDATE NetworkDevice
	SET NetworkDevice.DuplicateID = NULL
	WHERE EXISTS (
		SELECT 1
		FROM #DeletedNetworkDeviceID
		WHERE #DeletedNetworkDeviceID.DeviceID = NetworkDevice.DuplicateID
	)

	DELETE FROM NetworkDevice
	WHERE EXISTS (
		SELECT 1
		FROM #DeletedNetworkDeviceID
		WHERE #DeletedNetworkDeviceID.DeviceID = NetworkDevice.DeviceID
	)

	DELETE [User]
	FROM [User]
		INNER JOIN Organization ON Organization.OrganizationID = [User].UserOUID
	WHERE Organization.DomainID = @OrganizationID

	-- Disable constraints
	ALTER TABLE Domain NOCHECK CONSTRAINT FK_Domain_ID
	ALTER TABLE Organization NOCHECK CONSTRAINT FK_Organization_Domain

	DELETE FROM Organization WHERE DomainID = @OrganizationID

	DELETE FROM Domain WHERE OrganizationID = @OrganizationID

	-- Enable constraints
	ALTER TABLE Domain CHECK CONSTRAINT FK_Domain_ID
	ALTER TABLE Organization CHECK CONSTRAINT FK_Organization_Domain
	
	COMMIT WORK
GO

PRINT 'Creating procedure to rename a domain'
IF EXISTS (
        SELECT * FROM dbo.sysobjects
        WHERE [name] = 'DomainRename' AND xtype = 'P'
)
	DROP PROCEDURE DomainRename
GO
CREATE PROCEDURE DomainRename
	@OrganizationID int,
	@dn nvarchar(100),
	@flatname nvarchar(32)
AS
UPDATE domain
SET DN = @dn, FlatName = @flatname
WHERE OrganizationID = @OrganizationID
GO

PRINT 'Creating procedure to create an Organization entry'
IF EXISTS (
        SELECT * FROM dbo.sysobjects
        WHERE [name] = 'OrganizationCreate' AND xtype = 'P'
)
        DROP PROCEDURE OrganizationCreate
GO
CREATE PROCEDURE OrganizationCreate
	@OU_RDN		nvarchar(400),
	@DomainDN	nvarchar(100),
	@OU_GUID	binary(16) = NULL
AS
	-- Procedure starts here
	DECLARE @OrgID AS INT
	DECLARE @DomID AS INT

	-- Look for the specified domain
	SELECT @DomID = OrganizationID FROM Domain WHERE DN = @DomainDN

	-- Create an entry if not found
	IF (@DomID IS NULL)
	BEGIN
		EXEC DomainCreate @DomainDN
		SELECT @DomID = OrganizationID FROM Domain WHERE DN = @DomainDN
	END

	-- Look for the Organization Unit
	IF (@DomID IS NOT NULL)
	BEGIN
		SELECT @OrgID = OrganizationID 
			FROM Organization 
			WHERE RDN = @OU_RDN
			AND   DomainID = @DomID

		-- Did not find the OU's RDN, add an entry
		IF (@OrgID IS NULL)
		BEGIN
			INSERT INTO Organization(RDN, DomainID, GUID)
				VALUES (@OU_RDN, @DomID, @OU_GUID)
		END
	END
GO

PRINT 'Creating procedure to create an Organization DN entry'
IF EXISTS (
        SELECT * FROM dbo.sysobjects
        WHERE [name] = 'OrganizationDNCreate' AND xtype = 'P'
)
        DROP PROCEDURE OrganizationDNCreate
GO
CREATE PROCEDURE OrganizationDNCreate
	@OU_RDN		nvarchar(400),
	@DomainDN	nvarchar(100),
	@OU_GUID	binary(16) = NULL
AS
	-- Procedure starts here
	DECLARE @OrgID AS INT
	DECLARE @DomID AS INT

	-- Look for the specified domain
	SELECT @DomID = OrganizationID FROM Domain WHERE DN = @DomainDN

	-- Create an entry if not found
	IF (@DomID IS NULL)
	BEGIN
		EXEC DomainCreate @DomainDN
		SELECT @DomID = OrganizationID FROM Domain WHERE DN = @DomainDN
	END

	-- Look for the Organization Unit
	IF (@DomID IS NOT NULL)
	BEGIN
		SELECT @OrgID = OrganizationID 
			FROM Organization 
			WHERE RDN = @OU_RDN
			AND   DomainID = @DomID

		-- Did not find the OU's RDN, add an entry
		IF (@OrgID IS NULL)
		BEGIN
			INSERT INTO Organization(RDN, DomainID, GUID)
				VALUES (@OU_RDN, @DomID, @OU_GUID)
		END
	END
GO

PRINT 'Creating procedure to delete a computer'
IF EXISTS(SELECT * FROM sysobjects WHERE xtype = 'P'
	AND name = 'DeleteComputer'
)
	DROP PROCEDURE DeleteComputer
GO
CREATE PROCEDURE DeleteComputer
	@ComputerID	INT
AS
	IF (@ComputerID IS NULL)
		RETURN		-- No target, we can do nothing

	-- Get the DN of the computer
	DECLARE @ComputerDN nvarchar(600)
	DECLARE @ComputerOUID int
	SELECT @ComputerDN =
		'CN='+c.ComputerCN+','+ISNULL(o.RDN,'<unknown>')+','+ISNULL(d.DN,'')
		, @ComputerOUID = c.ComputerOUID
		FROM	Computer AS c,
			Organization AS o,
			Domain AS d
		WHERE c.ComputerID = @ComputerID	-- Right Computer
		  AND o.OrganizationID = c.ComputerOUID	-- Right Organization
		  AND o.DomainID = d.OrganizationID	-- Right Domain

	-- Drop a message in the Windows Application log
	DECLARE @msg nvarchar(1024)
	SET @msg = 'Deleting computer, ID = ' +
		STR(@ComputerID, 7) + ' DN = ' + @ComputerDN
	PRINT @msg

	DELETE FROM Member
		WHERE TargetTypeID = 1
		  AND TargetID = @ComputerID
	DELETE FROM PackageApplies
		WHERE TargetTypeID = 1
		  AND TargetID = @ComputerID
		  AND TargetOUID = @ComputerOUID
	DELETE FROM PolicyApplies
		WHERE TargetTypeID = 1
		  AND TargetID = @ComputerID
		  AND TargetOUID = @ComputerOUID
	UPDATE NetworkDevice
		SET ComputerID = NULL
		WHERE ComputerID = @ComputerID

	-- WiDep tables
	IF EXISTS (
		SELECT *
		FROM INFORMATION_SCHEMA.TABLES
		WHERE TABLE_NAME = 'RolloutGroupMember'
	)
	BEGIN
		DELETE FROM RolloutGroupMember
			WHERE MemberID = @ComputerID
			  AND MemberType = 1
		DELETE FROM HardwareAssessmentCache
			WHERE ComputerID = @ComputerID
	END

	DELETE FROM Computer
		WHERE ComputerID = @ComputerID
GO

PRINT 'Creating procedure to delete a set of computers'

-- DeleteComputers deletes all Computer records identified by
-- #Computer.ComputerID values

IF EXISTS(SELECT * FROM sysobjects WHERE xtype = 'P'
	AND name = 'DeleteComputers'
)
	DROP PROCEDURE DeleteComputers
GO
CREATE PROCEDURE DeleteComputers
AS
	SELECT	c.ComputerID, c.ComputerOUID
	INTO	#UnwantedComputerDetail
	FROM	#Computer tc
		INNER JOIN Computer c ON c.ComputerID = tc.ComputerID

	DELETE	m
	FROM	Member m
		INNER JOIN #UnwantedComputerDetail c
			ON m.TargetTypeID = 1
			AND m.TargetID = c.ComputerID

	DELETE	tp
	FROM	PackageApplies tp
		INNER JOIN #UnwantedComputerDetail c
			ON tp.TargetTypeID = 1
			AND tp.TargetID = c.ComputerID
			AND tp.TargetOUID = c.ComputerOUID

	DELETE	pa
	FROM	PolicyApplies pa
		INNER JOIN #UnwantedComputerDetail c
			ON pa.TargetTypeID = 1
			AND pa.TargetID = c.ComputerID
			AND pa.TargetOUID = c.ComputerOUID

	UPDATE NetworkDevice
		SET ComputerID = NULL
		WHERE ComputerID IN (
			SELECT ComputerID FROM #UnwantedComputerDetail
		)

	-- WiDep tables
	IF EXISTS (
		SELECT *
		FROM INFORMATION_SCHEMA.TABLES
		WHERE TABLE_NAME = 'RolloutGroupMember'
	)
	BEGIN
		DELETE	m
		FROM	RolloutGroupMember m
			INNER JOIN #UnwantedComputerDetail c
				ON m.MemberType = 1
				AND m.MemberID = c.ComputerID

		DELETE	hac
		FROM	HardwareAssessmentCache hac
			INNER JOIN #UnwantedComputerDetail c
				ON c.ComputerID = hac.ComputerID
	END

	DELETE	c
	FROM	Computer c
		INNER JOIN #UnwantedComputerDetail uc
			ON uc.ComputerID = c.ComputerID
GO

PRINT 'Creating procedure to delete a user'
IF EXISTS(SELECT * FROM sysobjects WHERE xtype = 'P'
	AND name = 'DeleteUser'
)
	DROP PROCEDURE DeleteUser
GO
CREATE PROCEDURE DeleteUser
	@UserID		INT
AS
	IF (@UserID IS NULL)
		RETURN		-- No target, we can do nothing

	-- Get the DN of the user
	DECLARE @UserDN nvarchar(600)
	DECLARE @UserOUID int
	SELECT @UserDN =
		'CN='+u.UserCN+','+ISNULL(o.RDN,'<unknown>')+','+ISNULL(d.DN,'')
		, @UserOUID = u.UserOUID
		FROM	[User] AS u,
			Organization AS o,
			Domain AS d
		WHERE u.UserID = @UserID		-- Right User
		  AND o.OrganizationID = u.UserOUID	-- Right Organization
		  AND o.DomainID = d.OrganizationID	-- Right Domain

	-- Drop a message in the Windows Application log
	DECLARE @msg nvarchar(1024)
	SET @msg = 'Deleting user, ID = ' +
		STR(@UserID, 7) + ' DN = ' + @UserDN
	PRINT @msg

	DELETE FROM Member
		WHERE TargetTypeID = 2
		  AND TargetID = @UserID
	DELETE FROM PackageApplies
		WHERE TargetTypeID = 2
		  AND TargetID = @UserID
		  AND TargetOUID = @UserOUID
	DELETE FROM PolicyApplies
		WHERE TargetTypeID = 2
		  AND TargetID = @UserID
		  AND TargetOUID = @UserOUID
	DELETE FROM [User]
		WHERE UserID = @UserID
GO

PRINT 'Creating procedure to delete a set of users'

-- DeleteUsers deletes all User records identified by #User.UserID
-- values

IF EXISTS(SELECT * FROM sysobjects WHERE xtype = 'P'
	AND name = 'DeleteUsers'
)
	DROP PROCEDURE DeleteUsers
GO
CREATE PROCEDURE DeleteUsers
AS
	SELECT	u.UserID, u.UserOUID
	INTO	#UnwantedUserDetail
	FROM	#User tu
		INNER JOIN [User] u ON u.UserID = tu.UserID

	DELETE	m
	FROM	Member m
		INNER JOIN #UnwantedUserDetail u
			ON m.TargetTypeID = 2
			AND m.TargetID = u.UserID

	DELETE	tp
	FROM	PackageApplies tp
		INNER JOIN #UnwantedUserDetail u
			ON tp.TargetTypeID = 2
			AND tp.TargetID = u.UserID
			AND tp.TargetOUID = u.UserOUID

	DELETE	pa
	FROM	PolicyApplies pa
		INNER JOIN #UnwantedUserDetail u
			ON pa.TargetTypeID = 2
			AND pa.TargetID = u.UserID
			AND pa.TargetOUID = u.UserOUID

	DELETE	u
	FROM	[User] u
		INNER JOIN #UnwantedUserDetail uu
			ON uu.UserID = u.UserID
GO

PRINT 'Creating procedure to delete a License Allocation'
IF EXISTS(SELECT * FROM sysobjects WHERE xtype = 'P'
	AND name = 'DeleteAllocation'
)
	DROP PROCEDURE DeleteAllocation
GO
CREATE PROCEDURE DeleteAllocation
	@AllocationID	INT
AS
	IF (@AllocationID IS NULL)
		RETURN		-- No target, we can do nothing

	-- Get the OrganizationDN owning the Allocation:
	DECLARE @OrganizationDN nvarchar(400)
	SELECT @OrganizationDN =
		ISNULL(o.RDN,'<unknown>')+','+ISNULL(d.DN,'')
		FROM	LicenseAllocation AS la,
			Organization AS o,
			Domain AS d
		WHERE la.AllocationID = @AllocationID	-- Right Allocation
		  AND o.OrganizationID = la.OrganizationID	-- Right OU
		  AND o.DomainID = d.OrganizationID	-- Right Domain

	-- Get the SoftwareProductName and Units
	DECLARE @SoftwareProductName nvarchar(256)
	DECLARE @Units int
	SELECT	@SoftwareProductName = sp.ProductName,
		@Units = la.UnitsAllocated
		FROM SoftwareProduct AS sp, LicenseAllocation AS la
		WHERE la.AllocationID = @AllocationID
		  AND la.SoftwareProductID = sp.SoftwareProductID

	-- Drop a message in the Windows Application log
	DECLARE @msg nvarchar(800)
	SET @msg = 'Deleting Allocation of ' + STR(@Units, 6) +
		' of ' + @SoftwareProductName + ' from ' + @OrganizationDN
	PRINT @msg

	DELETE from LicenseAllocation
		WHERE AllocationID = @AllocationID
GO

PRINT 'Creating procedure to delete a License Purchase'
IF EXISTS(SELECT * FROM sysobjects WHERE xtype = 'P'
	AND name = 'DeleteLicensePurchase'
)
	DROP PROCEDURE DeleteLicensePurchase
GO
CREATE PROCEDURE DeleteLicensePurchase
	@SoftwareProductID	INT, 
	@OrganizationID		INT,
	@ResellerID			INT,
	@Purchased			DATETIME,
	@OrderNumber		NVARCHAR(32)
AS
	IF (
		@SoftwareProductID IS NULL
		OR @OrganizationID IS NULL
		OR @ResellerID IS NULL
		OR @Purchased IS NULL
		-- Order number can be NULL
	)
	RETURN		-- No target, we can do nothing

	-- Get the OrganizationDN owning the purchase:
	DECLARE @OrganizationDN nvarchar(400)
	SELECT @OrganizationDN =
		ISNULL(o.RDN,'<unknown>')+','+ISNULL(d.DN,'')
		FROM
			Organization AS o,
			Domain AS d
		WHERE o.OrganizationID = @OrganizationID	-- Right OU
		  AND o.DomainID = d.OrganizationID	-- Right Domain

	-- Get the SoftwareProductName and Units
	DECLARE @SoftwareProductName nvarchar(256)
	SELECT	@SoftwareProductName = sp.ProductName
		FROM SoftwareProduct AS sp
		WHERE sp.SoftwareProductID = @SoftwareProductID

	-- Drop a message in the Windows Application log
	DECLARE @msg nvarchar(800)
	SET @msg = 'Deleting Purchase for software product ' + @SoftwareProductName +
		' made on ' + CONVERT(NVARCHAR(200), @Purchased) + ' for owner ' + @OrganizationDN
	PRINT @msg

	DELETE from LicensePurchase
		WHERE SoftwareProductID = @SoftwareProductID 
		  AND OrganizationID = @OrganizationID
		  AND ResellerID = @ResellerID
		  AND Purchased = @Purchased
		  AND OrderNumber = @OrderNumber
GO

PRINT 'Creating procedure to move computers to a new OU'
IF EXISTS(SELECT * FROM sysobjects WHERE xtype = 'P'
	AND name = 'MoveComputersToNewOU'
)
	DROP PROCEDURE MoveComputersToNewOU
GO
CREATE PROCEDURE MoveComputersToNewOU
AS
	-- DELETE existing computers with a matching CN in the new OUs
	SELECT	u.ComputerID
	INTO	#Computer
		FROM Computer AS k, Computer AS u, #ComputersToMove AS m
		WHERE k.ComputerID = m.ComputerID
		  AND u.ComputerID <> m.ComputerID
		  AND k.ComputerCN = u.ComputerCN
		  AND u.ComputerOUID = m.NewOUID

	EXEC DeleteComputers
	DROP TABLE #Computer
	
	UPDATE Installation
		SET OrganizationID = m.NewOUID
		FROM #ComputersToMove AS m
		WHERE Installation.ComputerID = m.ComputerID
		  AND Installation.UserID = 1	-- SYSTEM user
		  AND Installation.OrganizationID != m.NewOUID
	UPDATE PackageApplies
		SET TargetOUID = m.NewOUID
		FROM #ComputersToMove AS m
		WHERE TargetTypeID = 1
		  AND TargetID = m.ComputerID
		  AND TargetOUID != m.NewOUID
	UPDATE PolicyApplies
		SET TargetOUID = m.NewOUID
		FROM #ComputersToMove AS m
		WHERE TargetTypeID = 1
		  AND TargetID = m.ComputerID
		  AND TargetOUID != m.NewOUID
	UPDATE Computer
		SET ComputerOUID = m.NewOUID
		FROM #ComputersToMove AS m
		WHERE Computer.ComputerID = m.ComputerID
		  AND Computer.ComputerOUID != m.NewOUID
GO

PRINT 'Creating procedure to move a computer to a new OU'
IF EXISTS(SELECT * FROM sysobjects WHERE xtype = 'P'
	AND name = 'MoveComputerToNewOU'
)
	DROP PROCEDURE MoveComputerToNewOU
GO
CREATE PROCEDURE MoveComputerToNewOU
	@ComputerID	INT,
	@NewOUID	INT = 1		-- Default to Universal domain
AS
	IF (@ComputerID IS NULL OR @NewOUID IS NULL)
		RETURN		-- No target, we can do nothing

	-- DELETE an existing computer of this CN in the new OU
	DECLARE @toDelete INT
	SELECT @toDelete = u.ComputerID
		FROM Computer AS k, Computer AS u
		WHERE k.ComputerID = @ComputerID
		  AND u.ComputerID <> @ComputerID
		  AND k.ComputerCN = u.ComputerCN
		  AND u.ComputerOUID = @NewOUID

	IF @toDelete IS NOT NULL
	BEGIN
--		PRINT "Deleting Computer " + STR(@toDelete, 7) + ", it's in the way of renaming " +
--			STR(@ComputerID, 7)
		EXEC DeleteComputer @toDelete
	END

	-- Get the DN of the Organization:
	DECLARE @OUDN nvarchar(500)
	SELECT @OUDN = ISNULL(o.RDN,'<unknown>')+','+ISNULL(d.DN,'')
		FROM	Organization AS o,
			Domain AS d
		WHERE o.OrganizationID = @NewOUID
		  AND o.DomainID = d.OrganizationID

	-- Get the DN of the computer
	DECLARE @ComputerDN nvarchar(600)
	SELECT @ComputerDN =
		'CN='+c.ComputerCN+','+@OUDN
		FROM Computer AS c
		WHERE c.ComputerID = @ComputerID	-- Right Computer

	-- Drop a message in the Windows Application log
	DECLARE @msg nvarchar(1200)
	SET @msg = 'Moving computer, ID = ' +
		STR(@ComputerID, 7) + ' DN = ' + @ComputerDN + ' to ' + @OUDN
	PRINT @msg

	UPDATE Installation
		SET OrganizationID = @NewOUID
		WHERE ComputerID = @ComputerID
		  AND UserID = 1	-- SYSTEM user
	UPDATE PackageApplies
		SET TargetOUID = @NewOUID
		WHERE TargetTypeID = 1
		  AND TargetID = @ComputerID
	UPDATE PolicyApplies
		SET TargetOUID = @NewOUID
		WHERE TargetTypeID = 1
		  AND TargetID = @ComputerID
	UPDATE Computer
		SET ComputerOUID = @NewOUID
		WHERE ComputerID = @ComputerID
GO

PRINT 'Creating procedure to move a user to a new OU'
IF EXISTS(SELECT * FROM sysobjects WHERE xtype = 'P'
	AND name = 'MoveUsersToNewOU'
)
	DROP PROCEDURE MoveUsersToNewOU
GO
CREATE PROCEDURE MoveUsersToNewOU
AS
	-- DELETE an existing user of this CN or SAMAccountName in the new OU
	SELECT	u.UserID
	INTO	#User
		FROM [User] AS k, [User] AS u, #UsersToMove AS m
		WHERE k.UserID = m.UserID
		  AND u.UserID <> m.UserID
		  AND (k.UserCN = u.UserCN OR ISNULL(k.SAMAccountName, '') = ISNULL(u.SAMAccountName, ''))
		  AND u.UserOUID = m.NewOUID
		  
	EXEC DeleteUsers
	DROP TABLE #User

	UPDATE Installation
		SET OrganizationID = m.NewOUID
		FROM #UsersToMove AS m
		WHERE Installation.UserID = m.UserID
		  AND Installation.OrganizationID != m.NewOUID
	UPDATE PackageApplies
		SET TargetOUID = m.NewOUID
		FROM #UsersToMove AS m
		WHERE TargetTypeID = 2
		  AND TargetID = m.UserID
		  AND PackageApplies.TargetOUID != m.NewOUID
	UPDATE PolicyApplies
		SET TargetOUID = m.NewOUID
		FROM #UsersToMove AS m
		WHERE TargetTypeID = 2
		  AND TargetID = m.UserID
		  AND PolicyApplies.TargetOUID != m.NewOUID
	UPDATE [User]
		SET UserOUID = m.NewOUID
		FROM #UsersToMove AS m
		WHERE [User].UserID = m.UserID
		AND [User].UserOUID != m.NewOUID
GO

PRINT 'Creating procedure to move a user to a new OU'
IF EXISTS(SELECT * FROM sysobjects WHERE xtype = 'P'
	AND name = 'MoveUserToNewOU'
)
	DROP PROCEDURE MoveUserToNewOU
GO
CREATE PROCEDURE MoveUserToNewOU
	@UserID		INT,
	@NewOUID	INT = 1		-- Default to Unknown OU
AS
	IF (@UserID IS NULL OR @NewOUID IS NULL)
		RETURN		-- No target, we can do nothing

	DECLARE @toDelete INT

	-- DELETE an existing user of this CN in the new OU
	SELECT @toDelete = u.UserID
		FROM [User] AS k, [User] AS u
		WHERE k.UserID = @UserID
		  AND u.UserID <> @UserID
		  AND k.UserCN = u.UserCN
		  AND u.UserOUID = @NewOUID
	IF @toDelete IS NOT NULL
		EXEC DeleteUser @toDelete

	-- DELETE an existing user of this SAMAccountName in the new OU
	SELECT @toDelete = u.UserID
		FROM [User] AS k, [User] AS u
		WHERE k.UserID = @UserID
		  AND u.UserID <> @UserID
		  AND ISNULL(k.SAMAccountName, '') = ISNULL(u.SAMAccountName, '')
		  AND u.UserOUID = @NewOUID
	IF @toDelete IS NOT NULL
		EXEC DeleteUser @toDelete

	-- Get the DN of the Organization:
	DECLARE @OUDN nvarchar(500)
	SELECT @OUDN = ISNULL(o.RDN,'<unknown>')+','+ISNULL(d.DN,'')
		FROM	Organization AS o,
			Domain AS d
		WHERE o.OrganizationID = @NewOUID
		  AND o.DomainID = d.OrganizationID

	-- Get the DN of the User
	DECLARE @UserDN nvarchar(600)
	SELECT @UserDN =
		'CN='+u.UserCN+','+@OUDN
		FROM [User] AS u
		WHERE u.UserID = @UserID	-- Right User

	-- Drop a message in the Windows Application log
	DECLARE @msg nvarchar(1200)
	SET @msg = 'Moving user, ID = ' +
		STR(@UserID, 7) + ' DN = ' + @UserDN + ' to ' + @OUDN
	PRINT @msg

	UPDATE Installation
		SET OrganizationID = @NewOUID
		WHERE UserID = @UserID
	UPDATE PackageApplies
		SET TargetOUID = @NewOUID
		WHERE TargetTypeID = 2
		  AND TargetID = @UserID
	UPDATE PolicyApplies
		SET TargetOUID = @NewOUID
		WHERE TargetTypeID = 2
		  AND TargetID = @UserID
	UPDATE [User]
		SET UserOUID = @NewOUID
		WHERE UserID = @UserID
GO

PRINT 'Creating procedure to delete an OrganisationalUnit'
IF EXISTS(SELECT * FROM sysobjects WHERE xtype = 'P'
	AND name = 'DeleteOrganization'
)
	DROP PROCEDURE DeleteOrganization
GO
CREATE PROCEDURE DeleteOrganization
	@OrganizationID		INT
AS
	IF @OrganizationID IS NULL
	OR @OrganizationID = 1
	OR EXISTS(SELECT * FROM Domain WHERE @OrganizationID = OrganizationID)
		RETURN		-- No target, universal or domain: do nothing

	-- Get the DN and DomainID of the Organization:
	DECLARE @OUDN nvarchar(500)
	DECLARE @DomainID int
	SELECT	@OUDN = o.RDN+','+d.DN,
		@DomainID = o.DomainID
		FROM	Organization AS o,
			Domain AS d
		WHERE o.OrganizationID = @OrganizationID
		  AND o.DomainID = d.OrganizationID

	IF (@OUDN IS NULL)
		RETURN		-- Invalid, ignore it.

	-- Get the unknown OU for the domain, to move contents there
	DECLARE @UnknownOU int
	SELECT @UnknownOU = OrganizationID
		FROM Organization AS o
		WHERE o.RDN IS NULL
		  AND o.DomainID = @DomainID

	-- Drop a message in the Windows Application log
	DECLARE @msg nvarchar(600)
	SET @msg = 'Deleting OU, ID = ' +
		STR(@OrganizationID, 7) + ' DN = ' + @OUDN
	PRINT @msg

	-- Iterate through the Users in this Org, moving them to Unknown
	SELECT UserID, @UnknownOU AS NewOUID
	INTO #UsersToMove
	FROM [User] AS u
	WHERE u.UserOUID = @OrganizationID

	EXEC MoveUsersToNewOU
	DROP TABLE #UsersToMove

	-- Iterate through the Computers in this Org, moving them to Unknown
	SELECT ComputerID, @UnknownOU AS NewOUID
	INTO #ComputersToMove
	FROM [Computer] AS u
	WHERE u.ComputerOUID = @OrganizationID

	EXEC MoveComputersToNewOU
	DROP TABLE #ComputersToMove

	-- Iterate through the Groups in this Org, moving them to Unknown
	DECLARE @GroupID AS int
	DECLARE group_cur CURSOR FOR
		SELECT GroupID
		FROM [Group] AS g
		WHERE g.GroupOUID = @OrganizationID
	OPEN group_cur
	FETCH NEXT FROM group_cur INTO @GroupID
	WHILE @@FETCH_STATUS = 0
	BEGIN
		UPDATE [Group]
			SET GroupOUID = @UnknownOU
			WHERE GroupID = @GroupID
		FETCH NEXT FROM group_cur INTO @GroupID
	END
	CLOSE group_cur
	DEALLOCATE group_cur

	-- Iterate through the License Allocations in this Org, deleting them
	DECLARE @AllocationID AS int
	DECLARE allocation_cur CURSOR FOR
		SELECT AllocationID
		FROM LicenseAllocation AS la
		WHERE la.OrganizationID = @OrganizationID
	OPEN allocation_cur
	FETCH NEXT FROM allocation_cur INTO @AllocationID
	WHILE @@FETCH_STATUS = 0
	BEGIN
		EXEC DeleteAllocation @AllocationID
		FETCH NEXT FROM allocation_cur INTO @AllocationID
	END
	CLOSE allocation_cur
	DEALLOCATE allocation_cur
	
	-- Iterate through the License Purchases for this Org, deleting them
	DECLARE @SoftwareProductID AS int
	DECLARE @ResellerID AS int
	DECLARE @Purchased AS DATETIME
	DECLARE @OrderNumber AS NVARCHAR(32)	
	DECLARE purchase_cur CURSOR FOR
		SELECT SoftwareProductID, OrganizationID, ResellerID, Purchased, OrderNumber
		FROM LicensePurchase AS lp
		WHERE lp.OrganizationID = @OrganizationID
	OPEN purchase_cur
	FETCH NEXT FROM purchase_cur INTO @SoftwareProductID, @OrganizationID, @ResellerID, @Purchased, @OrderNumber
	WHILE @@FETCH_STATUS = 0
	BEGIN
		EXEC DeleteLicensePurchase @SoftwareProductID, @OrganizationID, @ResellerID, @Purchased, @OrderNumber
		FETCH NEXT FROM purchase_cur INTO @SoftwareProductID, @OrganizationID, @ResellerID, @Purchased, @OrderNumber
	END
	CLOSE purchase_cur
	DEALLOCATE purchase_cur

	-- Delete all Policy records affecting users/computers in this Org:
	DELETE FROM PackageApplies
		WHERE TargetOUID = @OrganizationID
	DELETE FROM PolicyApplies
		WHERE TargetOUID = @OrganizationID

	-- Finally delete the Organization
	DELETE FROM Organization
		WHERE OrganizationID = @OrganizationID
GO

IF EXISTS(SELECT * FROM sysobjects WHERE xtype = 'P'
	AND name = 'RenameOrganization'
)
	DROP PROCEDURE RenameOrganization
GO
CREATE PROCEDURE RenameOrganization
	@OrganizationID	INT,
	@RDN		nvarchar(400)
AS
	IF (@OrganizationID IS NULL)
		RETURN		-- No target, we can do nothing

	UPDATE Organization
		SET RDN = @RDN
		WHERE OrganizationID = @OrganizationID

	-- Drop a message in the Windows Application log
	IF (@@ROWCOUNT <> 0)
	BEGIN
		DECLARE @msg nvarchar(500)
		SET @msg = 'Renamed OU, ID = ' + STR(@OrganizationID, 7) +
			' to '+ @RDN
		PRINT @msg
	END
GO

PRINT 'Creating procedure to rename a Computer'
IF EXISTS(SELECT * FROM sysobjects WHERE xtype = 'P'
	AND name = 'RenameComputer'
)
	DROP PROCEDURE RenameComputer
GO
CREATE PROCEDURE RenameComputer
	@ComputerID	INT,
	@ComputerCN	varchar(64)
AS
	IF (@ComputerID IS NULL)
		RETURN		-- No target, we can do nothing

	UPDATE Computer
		SET ComputerCN = LOWER(@ComputerCN)
		WHERE ComputerID = @ComputerID

	-- Drop a message in the Windows Application log
	IF (@@ROWCOUNT <> 0)
	BEGIN
		DECLARE @msg varchar(256)
		SET @msg = 'Renamed Computer, ID = ' +
			STR(@ComputerID, 7) + ' to '+ @ComputerCN
		PRINT @msg
	END
GO

PRINT 'Creating procedure to rename a user'
IF EXISTS(SELECT * FROM sysobjects WHERE xtype = 'P'
	AND name = 'RenameUser'
)
	DROP PROCEDURE RenameUser
GO
CREATE PROCEDURE RenameUser
	@UserID		INT,
	@UserCN		varchar(64),
	@SAMAccountName varchar(20)
AS
	UPDATE [User]
		SET	UserCN = @UserCN,
			SAMAccountName = LOWER(@SAMAccountName)
		WHERE UserID = @UserID

	-- Drop a message in the Windows Application log
	IF (@@ROWCOUNT <> 0)
	BEGIN
		DECLARE @msg varchar(256)
		SET @msg = 'Renamed User, ID = ' +
			STR(@UserID, 7) + ' to '+ @UserCN +
			', SAMAccountName = '
			+ ISNULL(@SAMAccountName,'<null>')
		PRINT @msg
	END
GO

IF EXISTS(SELECT * FROM sysobjects WHERE xtype = 'P'
		AND name = 'ComputerGetAllByDomainID')
	DROP PROCEDURE ComputerGetAllByDomainID
GO
CREATE PROCEDURE ComputerGetAllByDomainID
	@ComputerDomainID		int
AS
	SELECT	ComputerID,
		ComputerOUID,
		ComputerCN,
		OperatingSystemID,
		c.GUID
	FROM	Computer AS c,
		Organization AS o
	WHERE	c.ComputerOUID = o.OrganizationID
	  AND	o.DomainID = @ComputerDomainID
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM sysobjects WHERE xtype = 'P'
		AND name = 'UserGetAllByDomainID')
	DROP PROCEDURE UserGetAllByDomainID
GO
CREATE PROCEDURE UserGetAllByDomainID
	@UserDomainID		int
AS
	SELECT	UserID,
		UserOUID,
		UserCN,
		u.GUID,
		SAMAccountName
	FROM	[User] AS u,
		Organization AS o
	WHERE	u.UserOUID = o.OrganizationID
	  AND	o.DomainID = @UserDomainID
	RETURN @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM sysobjects WHERE xtype = 'P'
		AND name = 'GroupReplaceSubsetByDomainID')
	DROP PROCEDURE GroupReplaceSubsetByDomainID
GO
-- Replace the record subset selected by (@DomainID)
-- using unique identifier (GUID)
-- updating fields (GroupID, GroupCN)
CREATE PROCEDURE GroupReplaceSubsetByDomainID
	@DomainID	int,
	@ExcludeWithMemberTargetTypeID	int = 0,
	@ParentOU	nvarchar(400) = NULL
AS
	DECLARE @count AS int
	SET @count = 0

	CREATE INDEX [TempGroupByGUID]
		ON #Group (GUID)

	CREATE TABLE #DeletedGroup(
		GroupID	INT
	)
	CREATE INDEX [TempDeletedGroupByID]
		ON #DeletedGroup (GroupID)

	BEGIN TRANSACTION
	IF ISNULL(@ParentOU, '') = ''
		BEGIN 		
			INSERT	#DeletedGroup(GroupID)
			SELECT	g.GroupID
			FROM	[Group] g
				INNER JOIN Organization o ON o.OrganizationID = g.GroupOUID
			WHERE	o.DomainID = @DomainID
			AND NOT EXISTS (
				SELECT	*
				FROM	#Group AS t
				WHERE	g.GUID = t.GUID
			)
			AND NOT EXISTS (
				SELECT *
				FROM Member m
				WHERE g.GroupID = m.GroupID
				AND TargetTypeID = @ExcludeWithMemberTargetTypeID 
			)

			DELETE	p
			FROM	Policy p
				INNER JOIN #DeletedGroup g ON g.GroupID = p.AccessGroupID
		
			DELETE	m
			FROM	TransitiveMember AS m
				INNER JOIN #DeletedGroup g ON g.GroupID = m.GroupID
			-- print 'deleted '+str(@@rowcount)+' transitive memberships of deleted groups'
		
			DELETE	m
			FROM	Member AS m
				INNER JOIN #DeletedGroup g ON g.GroupID = m.GroupID
			-- print 'deleted '+str(@@rowcount)+' memberships of deleted groups'
		END
	ELSE
		BEGIN
			DECLARE @ParentOUReverse nvarchar(400)
 
			-- Reverse the DN
			IF (@ParentOU IS NULL OR @ParentOU = '')
				SET @ParentOUReverse = ''
			ELSE
				EXEC ReverseDN @ParentOU, @ParentOUReverse OUTPUT

			-- Delete RSoP membership under selected OU
			DELETE	m
			FROM	Member AS m,
					[Group] AS g,
					Target(2) AS t,
					Organization AS o
			WHERE	g.GroupID = m.GroupID
			  AND	g.GroupCN = '+RSoP'
			  AND	t.TargetID = m.TargetID
			  AND	t.TargetTypeID = m.TargetTypeID
			  AND	o.OrganizationID = t.TargetOUID
			  AND	o.DomainID = @DomainID
			  AND	(o.RDNReverse+',') LIKE
					(
						CASE @ParentOUReverse
						WHEN '' THEN '%'
						ELSE @ParentOUReverse+',%'
						END
					) --Sub-OU
			  AND	m.TargetTypeID <> @ExcludeWithMemberTargetTypeID
			-- print 'deleted '+str(@@rowcount)+' memberships of RSoP groups'
		
			-- Delete RSoP group with no membership
			INSERT	#DeletedGroup(GroupID)
			SELECT	g.GroupID
			FROM	[Group] as g
			WHERE	g.GroupCN = '+RSoP'
			  AND	NOT EXISTS
					(
						SELECT GroupID
						FROM dbo.Member AS m
						WHERE m.GroupID = g.GroupID
					)

			DELETE	pa
			FROM	PackageApplies as pa
					INNER JOIN #DeletedGroup dg ON dg.GroupID = pa.TargetID AND pa.TargetTypeID = 3 -- RSOP Group
			DELETE	p
			FROM	PolicyApplies as p
					INNER JOIN #DeletedGroup dg ON dg.GroupID = p.TargetID AND p.TargetTypeID = 3 -- RSOP Group	
		END

	DELETE	g
	FROM	[Group] AS g
		INNER JOIN #DeletedGroup dg ON dg.GroupID = g.GroupID
	-- print 'deleted '+str(@@rowcount)+' groups'

	UPDATE [Group]
		SET	GroupOUID = t.GroupOUID,
			GroupCN = t.GroupCN,
			GroupType = t.GroupType
		FROM	#Group AS t
		WHERE	[Group].GUID = t.GUID
		  AND (	[Group].GroupOUID <> t.GroupOUID
		     OR	[Group].GroupCN <> t.GroupCN
		     OR ISNULL([Group].GroupType, 0) <> ISNULL(t.GroupType, 0))
	SET @count = @@ROWCOUNT
	-- print 'updated '+str(@count)+' groups'

	INSERT [Group] (
		GroupCN,
		GUID,
		GroupOUID,
		GroupType
	)
		SELECT	GroupCN,
			GUID,
			GroupOUID,
			GroupType
		FROM	#Group AS t
		WHERE NOT EXISTS(	-- Current record doesn't exist
			SELECT	*
			FROM	[Group]
			WHERE	[Group].GUID = t.GUID
		)
	SET @count = @count + @@ROWCOUNT
	-- print 'groups updated/inserted '+str(@count)

	DROP TABLE #Group	-- Drop the temporary table
	COMMIT WORK
	RETURN @count
GO

IF EXISTS(SELECT * FROM sysobjects WHERE xtype = 'P'
		AND name = 'NetworkLocationReplaceSubsetByDomainID')
	DROP PROCEDURE NetworkLocationReplaceSubsetByDomainID
GO
CREATE PROCEDURE NetworkLocationReplaceSubsetByDomainID
	@DomainID	int
AS
	-- Insert NetworkLocations that arent already in the database
	INSERT INTO NetworkLocation (
		[Name],
		DN,
		AutoPopulated,
		Enabled,
		DomainID)
	Select 
		[Name],
		DN,
		AutoPopulated,
		Enabled,
		@DomainID
	FROM #NetworkLocation as tnl
	WHERE tnl.[Name] not in
	(
		SELECT [Name]
		FROM NetworkLocation
	)


	-- Update NetwokLocations that are already in the database
	UPDATE NetworkLocation
	SET DN = tnl.DN
	FROM #NetworkLocation as tnl where tnl.Name = NetworkLocation.[Name]

	-- Delete any NetworkLocations that no longer appear
	-- begin by cleaning up the NetworkLocation's subnets
	Delete FROM Subnet
	WHERE Subnet.NetworkLocationID in
	(
		SELECT NetworkLocationID
		FROM NetworkLocation
		WHERE NetworkLocation.DomainID = @DomainID
			AND NetworkLocation.Name NOT IN
			(
				SELECT Name
				FROM #NetworkLocation
			)
	)
		
	DELETE FROM NetworkLocation
	WHERE NetworkLocation.DomainID = @DomainID
		AND NetworkLocation.Name NOT IN
		(
			SELECT Name
			FROM #NetworkLocation
		)
GO

IF EXISTS(SELECT * FROM sysobjects WHERE xtype = 'P'
		AND name = 'SubnetReplaceSubsetByDomainID')
	DROP PROCEDURE SubnetReplaceSubsetByDomainID
GO
CREATE PROCEDURE SubnetReplaceSubsetByDomainID
	@DomainID	int
AS
	-- Deal with subnets
	-- Insert Subnets that arent already in database

	INSERT INTO Subnet (
		IPSubnet,
		IPSubnetMask,
		AutoPopulated,
		Enabled,
		NetworkLocationID
	)
	Select IPSubnet, IPSubnetMask, AutoPopulated, Enabled, NetworkLocationID
	FROM #Subnet as ts
	WHERE NOT EXISTS
	(
		SELECT *
		FROM Subnet as s2
		WHERE 	s2.IPSubnet = ts.IPSubnet
		AND	s2.IPSubnetMask = ts.IPSubnetMask
		AND	s2.NetworkLocationID = ts.NetworkLocationID
	)

	-- Delete subnets that are no longer in AD
	DELETE FROM Subnet
	WHERE NOT EXISTS
	(
		SELECT *
		FROM #Subnet
		WHERE 	Subnet.IPSubnet = #Subnet.IPSubnet
		AND	Subnet.IPSubnetMask = #Subnet.IPSubnetMask
		AND	Subnet.NetworkLocationID = #Subnet.NetworkLocationID
	)
	AND NetworkLocationID IN
	(
		SELECT NetworkLocationID
		FROM NetworkLocation
		WHERE DomainID = @DomainID
	)

GO


IF EXISTS(SELECT * FROM sysobjects WHERE xtype = 'P'
		AND name = 'MemberReplaceSubsetByDomainID')
	DROP PROCEDURE MemberReplaceSubsetByDomainID
GO
CREATE PROCEDURE MemberReplaceSubsetByDomainID
	@DomainID	int,
	@ExcludeWithMemberTargetTypeID	int = 0,
	@LimitOU	bit = 0
AS
	DECLARE @count AS int
	SET @count = 0

	CREATE INDEX [TempMemberByGroupID]
		ON #Member (GroupID, TargetTypeID, TargetID)

	BEGIN TRANSACTION
	IF @LimitOU = 0
		BEGIN
			DELETE	m
			FROM	Member m
				INNER JOIN [Group] g ON g.GroupID = m.GroupID
				INNER JOIN Organization o ON o.OrganizationID = g.GroupOUID
			WHERE	o.DomainID = @DomainID
			AND m.TargetTypeID <> @ExcludeWithMemberTargetTypeID
				AND NOT EXISTS(
					SELECT	1
					FROM	#Member AS t
					WHERE	t.GroupID = m.GroupID
						AND t.TargetTypeID = m.TargetTypeID
						AND t.TargetID = m.TargetID
				)
			-- print 'deleted '+str(@@rowcount)+' deleted memberships of groups'

			UPDATE Member
			SET	MemberMode = t.MemberMode
			FROM	#Member AS t
			WHERE	Member.GroupID = t.GroupID
				AND Member.TargetTypeID = t.TargetTypeID
				AND Member.TargetID = t.TargetID
				AND Member.MemberMode <> t.MemberMode
			SET @count = @@ROWCOUNT
			-- print 'updated '+str(@count)+' memberships'
		END

	INSERT Member (GroupID, TargetTypeID, TargetID, MemberMode)
		SELECT	GroupID, TargetTypeID, TargetID, MemberMode
		FROM	#Member AS t
		WHERE	NOT EXISTS(	-- Current record doesn't exist
				SELECT	1
				FROM	Member
				WHERE	Member.GroupID = t.GroupID
					AND Member.TargetTypeID = t.TargetTypeID
					AND Member.TargetID = t.TargetID
			)
	SET @count = @count + @@ROWCOUNT
	-- print 'memberships updated/inserted '+str(@count)
	DROP TABLE #Member	-- Drop the temporary table
	COMMIT WORK
	RETURN @count
GO

IF EXISTS(SELECT * FROM sysobjects WHERE xtype = 'P'
		AND name = 'GroupGetAllByDomainID')
	DROP PROCEDURE GroupGetAllByDomainID
GO
CREATE PROCEDURE GroupGetAllByDomainID
	@DomainID		int
AS
	SELECT	[Group].GroupID,
		[Group].GUID,
		[Group].GroupCN,
		[Group].GroupOUID,
		[Group].GroupType
	FROM	[Group],
		Organization AS o
	WHERE	GroupOUID = o.OrganizationID
	  AND	o.DomainID = @DomainID
GO

PRINT 'Creating procedure to get all targets (computers, users, groups) by CN'
IF EXISTS (
	SELECT * FROM dbo.sysobjects
	WHERE [name] = 'TargetGetAllByCN' AND xtype = 'P'
)
	DROP PROCEDURE TargetGetAllByCN
GO
CREATE PROCEDURE TargetGetAllByCN
	@CN		nvarchar(400),
	@Computers	bit = 1,
	@Users		bit = 1,
	@Groups		bit = 1
AS
	SELECT	Targets.*,
		o.RDN + ',' + d.DN AS TargetLocation,
		o.RDN AS TargetOrganization,
		d.DN AS TargetDomain
	FROM
	(
		SELECT	c.ComputerID AS TargetID,
			c.ComputerOUID AS TargetOUID,
			c.ComputerCN AS TargetCN,
			c.GUID AS TargetGUID,
			1 AS TargetType
		FROM	Computer c
		WHERE	c.ComputerCN LIKE @CN
		  AND	@Computers = 1
		UNION
		SELECT	u.UserID AS TargetID,
			u.UserOUID AS TargetOUID,
			u.UserCN AS TargetCN,
			u.GUID AS TargetGUID,
			2 AS TargetType
		FROM	[User] u
		WHERE	u.UserCN LIKE @CN
		  AND	@Users = 1
		UNION
		SELECT	g.GroupID AS TargetID,
			g.GroupOUID AS TargetOUID,
			g.GroupCN AS TargetCN,
			g.GUID AS TargetGUID,
			3 AS TargetType
		FROM	[Group] g
		WHERE	g.GroupCN LIKE @CN
		  AND	@Groups = 1
	) As Targets,
		Organization o,
		Domain d
	WHERE	o.OrganizationID = Targets.TargetOUID
	  AND	o.DomainID = d.OrganizationID
	  AND	d.DN IS NOT NULL
	  AND	o.RDN IS NOT NULL
GO

PRINT 'Creating procedure to get all targets (computers, users, groups) by OUID'
IF EXISTS (
	SELECT * FROM dbo.sysobjects
	WHERE [name] = 'TargetGetAllByOUID' AND xtype = 'P'
)
	DROP PROCEDURE TargetGetAllByOUID
GO

CREATE PROCEDURE TargetGetAllByOUID
	@OUID		int,
	@Computers	bit = 1,
	@Users		bit = 1,
	@Groups		bit = 1
AS
	SELECT	Targets.*,
		o.RDN + ',' + d.DN AS TargetLocation,
		o.RDN AS TargetOrganization,
		d.DN AS TargetDomain
	FROM
	(
		SELECT	c.ComputerID AS TargetID,
			c.ComputerOUID AS TargetOUID,
			c.ComputerCN AS TargetCN,
			c.GUID AS TargetGUID,
			1 AS TargetType
		FROM	Computer c
		WHERE	c.ComputerOUID = @OUID
		  AND	@Computers = 1
		UNION
		SELECT	u.UserID AS TargetID,
			u.UserOUID AS TargetOUID,
			u.UserCN AS TargetCN,
			u.GUID AS TargetGUID,
			2 AS TargetType
		FROM	[User] u
		WHERE	u.UserOUID = @OUID
		  AND	@Users = 1
		UNION
		SELECT	g.GroupID AS TargetID,
			g.GroupOUID AS TargetOUID,
			g.GroupCN AS TargetCN,
			g.GUID AS TargetGUID,
			3 AS TargetType
		FROM	[Group] g
		WHERE	g.GroupOUID = @OUID
		  AND	@Groups = 1
	) As Targets,
		Organization o,
		Domain d
	WHERE	o.OrganizationID = Targets.TargetOUID
	  AND	o.DomainID = d.OrganizationID

GO

PRINT 'Creating procedure to get all targets (computers, users, groups) by GroupID'
IF EXISTS (
	SELECT * FROM dbo.sysobjects
	WHERE [name] = 'TargetGetAllByGroupID' AND xtype = 'P'
)
	DROP PROCEDURE TargetGetAllByGroupID
GO

CREATE PROCEDURE TargetGetAllByGroupID
	@GroupID	int,
	@Computers	bit = 1,
	@Users		bit = 1,
	@Groups		bit = 1
AS
	SELECT	Targets.*,
		o.RDN + ',' + d.DN AS TargetLocation,
		o.RDN AS TargetOrganization,
		d.DN AS TargetDomain
	FROM
	(
		SELECT	c.ComputerID AS TargetID,
			c.ComputerOUID AS TargetOUID,
			c.ComputerCN AS TargetCN,
			c.GUID AS TargetGUID,
			1 AS TargetType
		FROM	Computer c, Member m
		WHERE	c.ComputerID = m.TargetID
		  AND	m.GroupID = @GroupID
		  AND   m.TargetTypeID = 1
		  AND	@Computers = 1
		UNION
		SELECT	u.UserID AS TargetID,
			u.UserOUID AS TargetOUID,
			u.UserCN AS TargetCN,
			u.GUID AS TargetGUID,
			2 AS TargetType
		FROM	[User] u, Member m
		WHERE	u.UserID = m.TargetID
		  AND	m.GroupID = @GroupID
		  AND   m.TargetTypeID = 2
		  AND	@Users = 1
		UNION
		SELECT	g.GroupID AS TargetID,
			g.GroupOUID AS TargetOUID,
			g.GroupCN AS TargetCN,
			g.GUID AS TargetGUID,
			3 AS TargetType
		FROM	[Group] g, Member m
		WHERE	g.GroupID = m.TargetID
		  AND	m.GroupID = @GroupID
		  AND   m.TargetTypeID = 3
		  AND	@Groups = 1
	) As Targets,
		Organization o,
		Domain d
	WHERE	o.OrganizationID = Targets.TargetOUID
	  AND	o.DomainID = d.OrganizationID

GO

PRINT 'Creating procedure to get all targets (computers, users, groups) by CN and DomainID'
IF EXISTS (
	SELECT * FROM dbo.sysobjects
	WHERE [name] = 'TargetGetAllByDomainIDCN' AND xtype = 'P'
)
	DROP PROCEDURE TargetGetAllByDomainIDCN
GO
CREATE PROCEDURE TargetGetAllByDomainIDCN
	@DomainID	int,
	@CN		nvarchar(400),
	@Computers	bit = 1,
	@Users		bit = 1,
	@Groups		bit = 1
AS
	SELECT	Targets.*,
		o.RDN + ',' + d.DN AS TargetLocation,
		o.RDN AS TargetOrganization,
		d.DN AS TargetDomain
	FROM
	(
		SELECT	c.ComputerID AS TargetID,
			c.ComputerOUID AS TargetOUID,
			c.ComputerCN AS TargetCN,
			c.GUID AS TargetGUID,
			1 AS TargetType
		FROM	Computer c
		WHERE	c.ComputerCN LIKE @CN
		  AND	@Computers = 1
		UNION
		SELECT	u.UserID AS TargetID,
			u.UserOUID AS TargetOUID,
			u.UserCN AS TargetCN,
			u.GUID AS TargetGUID,
			2 AS TargetType
		FROM	[User] u
		WHERE	u.UserCN LIKE @CN
		  AND	@Users = 1
		UNION
		SELECT	g.GroupID AS TargetID,
			g.GroupOUID AS TargetOUID,
			g.GroupCN AS TargetCN,
			g.GUID AS TargetGUID,
			3 AS TargetType
		FROM	[Group] g
		WHERE	g.GroupCN LIKE @CN
		  AND	@Groups = 1
	) As Targets,
		Organization o,
		Domain d
	WHERE	o.OrganizationID = Targets.TargetOUID
	  AND	o.DomainID = d.OrganizationID
	  AND	d.DN IS NOT NULL
	  AND	o.RDN IS NOT NULL
	  AND	d.OrganizationID = @DomainID
GO

PRINT 'Creating procedure to get all targets by OUID for a GroupType'
IF EXISTS (
	SELECT * FROM dbo.sysobjects
	WHERE [name] = 'TargetGetAllByOUIDGroupType' AND xtype = 'P'
)
	DROP PROCEDURE TargetGetAllByOUIDGroupType
GO

CREATE PROCEDURE TargetGetAllByOUIDGroupType
	@OUID		int,
	@GroupType	int,
	@Computers	bit = 1,
	@Users		bit = 1,
	@Groups		bit = 1
AS
	SELECT	Targets.*,
		o.RDN + ',' + d.DN AS TargetLocation,
		o.RDN AS TargetOrganization,
		d.DN AS TargetDomain
	FROM
	(
		SELECT	c.ComputerID AS TargetID,
			c.ComputerOUID AS TargetOUID,
			c.ComputerCN AS TargetCN,
			c.GUID AS TargetGUID,
			1 AS TargetType
		FROM	Computer c
		WHERE	c.ComputerOUID = @OUID
		  AND	@Computers = 1
		UNION
		SELECT	u.UserID AS TargetID,
			u.UserOUID AS TargetOUID,
			u.UserCN AS TargetCN,
			u.GUID AS TargetGUID,
			2 AS TargetType
		FROM	[User] u
		WHERE	u.UserOUID = @OUID
		  AND	@Users = 1
		UNION
		SELECT	g.GroupID AS TargetID,
			g.GroupOUID AS TargetOUID,
			g.GroupCN AS TargetCN,
			g.GUID AS TargetGUID,
			3 AS TargetType
		FROM	[Group] g
		WHERE	g.GroupOUID = @OUID
		  AND	@Groups = 1
		  AND	(
				@GroupType IS NULL OR
				@GroupType = 0 OR
				(
					-- Global groups can only have Global groups as members
					@GroupType & 0x02 = 0x02 AND (
						g.GroupType IS NULL OR
						g.GroupType & 0x02 = 0x02
					)
				) OR
				(
					-- Local groups can have any groups as members
					@GroupType & 0x04 = 0x04
				) OR
				(
					-- Universal groups can only have Global and Universal groups as members
					@GroupType & 0x08 = 0x08 AND (
						g.GroupType IS NULL OR
						g.GroupType & 0x02 = 0x02 OR
						g.GroupType & 0x08 = 0x08
					)
				)
			)
	) As Targets,
		Organization o,
		Domain d
	WHERE	o.OrganizationID = Targets.TargetOUID
	  AND	o.DomainID = d.OrganizationID

GO

PRINT 'Creating procedure to get all targets by CN and DomainID for a GroupType'
IF EXISTS (
	SELECT * FROM dbo.sysobjects
	WHERE [name] = 'TargetGetAllByDomainIDCNGroupType' AND xtype = 'P'
)
	DROP PROCEDURE TargetGetAllByDomainIDCNGroupType
GO
CREATE PROCEDURE TargetGetAllByDomainIDCNGroupType
	@DomainID	int,
	@CN		nvarchar(400),
	@GroupType	int,
	@Computers	bit = 1,
	@Users		bit = 1,
	@Groups		bit = 1
AS
	SELECT	Targets.*,
		o.RDN + ',' + d.DN AS TargetLocation,
		o.RDN AS TargetOrganization,
		d.DN AS TargetDomain
	FROM
	(
		SELECT	c.ComputerID AS TargetID,
			c.ComputerOUID AS TargetOUID,
			c.ComputerCN AS TargetCN,
			c.GUID AS TargetGUID,
			1 AS TargetType
		FROM	Computer c
		WHERE	c.ComputerCN LIKE @CN
		  AND	@Computers = 1
		UNION
		SELECT	u.UserID AS TargetID,
			u.UserOUID AS TargetOUID,
			u.UserCN AS TargetCN,
			u.GUID AS TargetGUID,
			2 AS TargetType
		FROM	[User] u
		WHERE	u.UserCN LIKE @CN
		  AND	@Users = 1
		UNION
		SELECT	g.GroupID AS TargetID,
			g.GroupOUID AS TargetOUID,
			g.GroupCN AS TargetCN,
			g.GUID AS TargetGUID,
			3 AS TargetType
		FROM	[Group] g
		WHERE	g.GroupCN LIKE @CN
		  AND	@Groups = 1
		  AND	(
				@GroupType IS NULL OR
				@GroupType = 0 OR
				(
					-- Global groups can only have Global groups as members
					@GroupType & 0x02 = 0x02 AND (
						g.GroupType IS NULL OR
						g.GroupType & 0x02 = 0x02
					)
				) OR
				(
					-- Local groups can have any groups as members
					@GroupType & 0x04 = 0x04
				) OR
				(
					-- Universal groups can only have Global and Universal groups as members
					@GroupType & 0x08 = 0x08 AND (
						g.GroupType IS NULL OR
						g.GroupType & 0x02 = 0x02 OR
						g.GroupType & 0x08 = 0x08
					)
				)
			)
	) As Targets,
		Organization o,
		Domain d
	WHERE	o.OrganizationID = Targets.TargetOUID
	  AND	o.DomainID = d.OrganizationID
	  AND	d.DN IS NOT NULL
	  AND	o.RDN IS NOT NULL
	  AND	d.OrganizationID = @DomainID
GO

PRINT 'Creating procedure to get all members of a group, including members of child groups'
IF EXISTS (
	SELECT * FROM dbo.sysobjects
	WHERE [name] = 'TransitiveMemberFindByGroupID' AND xtype = 'P'
)
	DROP PROCEDURE TransitiveMemberFindByGroupID
GO
CREATE PROCEDURE TransitiveMemberFindByGroupID
	@GroupID	int,
	@Disposition	int = 1		-- 1 = Allow, 2 = Deny, 3 = both
AS
	DECLARE @TargetTypeGroup int
	SET @TargetTypeGroup = 3
	DECLARE	@Allow	bit
	SET	@Allow = CASE WHEN (@Disposition & 1) <> 0 THEN 1 ELSE 0 END
	DECLARE	@Deny	bit
	SET	@Deny = CASE WHEN (@Disposition & 2) <> 0 THEN 1 ELSE 0 END

	-- The #TransitiveMember table must have already been created:
	DELETE FROM #TransitiveMember	-- Start clean

	-- Start with just the Group we're expanding.
	-- Note this *DOES NOT WORK* for AuthenticatedUsers (GroupID=1),
	-- because the domain is not known.
	INSERT #TransitiveMember(GroupID, TargetTypeID, TargetID)
	VALUES	(@GroupID, @TargetTypeGroup, @GroupID)

	-- Add all members (unless a denied non-group) of every group already added
	DECLARE @added int
	SET @added = 1
	WHILE @added > 0
	BEGIN
		INSERT	#TransitiveMember (GroupID, TargetTypeID, TargetID, MemberMode)
			SELECT DISTINCT
				@GroupID, m.TargetTypeID, m.TargetID,
				CASE WHEN parent.MemberMode <> 1
				THEN	parent.MemberMode -- Parent is denied or Always, so we are
				ELSE	m.MemberMode
				END
			FROM	Member AS m,		-- The member we're considering adding
				#TransitiveMember AS parent	-- its parent
			WHERE	NOT EXISTS(		-- an existing entry that prevents us
				SELECT * FROM #TransitiveMember AS exist
				WHERE	m.TargetTypeID = exist.TargetTypeID
				  AND	m.TargetID = exist.TargetID
				  AND (	(CASE WHEN parent.MemberMode <> 1
					THEN	parent.MemberMode -- Parent is denied or Always, so we are
					ELSE	m.MemberMode
					END) = exist.MemberMode	-- Inserting same mode
				    OR	(exist.MemberMode = 0	-- Existing deny + normal allow
					AND m.MemberMode = 1
					AND parent.MemberMode = 1
					AND m.TargetTypeID <> @TargetTypeGroup -- not a group
				    	)	-- The allow is overridden for this principal
				      )
				)
			  AND	parent.TargetTypeID = @TargetTypeGroup	-- parent is a Group
			  AND	parent.TargetID = m.GroupID		-- parent is ours
			  -- Don't insert Allows if we don't want them (must keep denies):
			  AND	(@Allow = 1 OR parent.MemberMode = 0 OR m.MemberMode = 0)
		SET @added = @@ROWCOUNT
		--PRINT 'added '+str(@added)+' transitive memberships'
	END

	-- REVISIT: A similar loop is needed to process subordinate organizations,
	-- allowing for BlockInheritance (=deny) and No-Override (Always).

	-- If AuthenticatedUsers is in the list of memberships,
	-- we must process it specially.
	DECLARE	@AllUsersMode	int
	SELECT @AllUsersMode = MIN(MemberMode) FROM #TransitiveMember
	WHERE TargetTypeID = @TargetTypeGroup AND TargetID = 1

	IF @AllUsersMode = 0		-- Deny All, delete all Allows except Groups
	BEGIN
		DELETE	#TransitiveMember
		WHERE	TargetTypeID <> @TargetTypeGroup
		AND	MemberMode > 0
		-- print 'All denied, deleted allows'
	END

	IF (@AllUsersMode IS NOT NULL	-- AuthenticatedUsers is in the list and
	AND (@Deny = 1 AND @AllUsersMode = 0)	-- we want the denies, or
	  OR (@Allow = 1 AND @AllUsersMode > 0)	-- all are allowed and we want them
	)
	BEGIN
		-- Add all principals (from same domain) to the list
		INSERT	#TransitiveMember (GroupID, TargetTypeID, TargetID, MemberMode)
		SELECT	@GroupID, TargetTypeID, TargetID, @AllUsersMode
		FROM	(			-- Principals in same Domain as Group
			 SELECT	2 AS TargetTypeID,
			 	UserID AS TargetID,
				UserOUID AS OrganizationID
			 FROM	[User]
			UNION
			 SELECT	1 AS TargetTypeID,
			 	ComputerID AS TargetID,
				ComputerOUID AS OrganizationID
			 FROM	Computer
			) AS principal,
			Organization AS o,	-- Organization of Principal
			Organization AS go,	-- Organization of Group
			[Group] AS g		-- Group to populate
		WHERE	principal.OrganizationID = o.OrganizationID
		  AND	o.DomainID = go.DomainID -- In same domain
		  AND	go.OrganizationID = g.GroupOUID -- as the group
		  AND	g.GroupID = @GroupID
		  AND NOT EXISTS(		-- Except existing members
		  	SELECT * FROM #TransitiveMember AS tm
			WHERE	principal.TargetTypeID = tm.TargetTypeID
			  AND	principal.TargetID = tm.TargetID
		  )
	END

	-- Delete allows that aren't wanted, are surpassed or are denied
	DELETE tm
	FROM	#TransitiveMember AS tm
	WHERE	tm.MemberMode > 0			-- Allowed and
	  AND (	@Allow = 0				-- We don't want allows
	     OR	EXISTS(					-- or it's...
		SELECT * FROM #TransitiveMember as x
		WHERE	tm.TargetTypeID = x.TargetTypeID
		  AND	tm.TargetID = x.TargetID
		  AND (	x.MemberMode = 0		-- ...denied, or
		     OR	x.MemberMode > tm.MemberMode)	-- ...surpassed
		)
	)

	-- Delete all denies if we don't want to return them
	IF @Deny = 0
		DELETE	tm
		FROM	#TransitiveMember AS tm
		WHERE	tm.MemberMode = 0

	-- We could use flags to delete groups and/or organizations here.
GO

PRINT 'Creating procedure to get all principals in a group, including via child groups'
IF EXISTS (
	SELECT * FROM dbo.sysobjects
	WHERE [name] = 'TransitiveMemberGetAllByGroupIDPolicyGUID' AND xtype = 'P'
)
	DROP PROCEDURE TransitiveMemberGetAllByGroupIDPolicyGUID
GO

CREATE PROCEDURE TransitiveMemberGetAllByGroupIDPolicyGUID
	@GroupID	int,
	@PolicyGUID	binary(16) = NULL
AS
	DECLARE @TargetTypeGroup int
	SET @TargetTypeGroup = 3

	-- Set up the temporary table
	IF OBJECT_ID('tempdb..#TransitiveMember') IS NULL
		CREATE TABLE #TransitiveMember (
			GroupID			int NOT NULL,
			TargetTypeID		int NOT NULL,
			TargetID		int NOT NULL,
			MemberMode		int NOT NULL DEFAULT 1
		)
	EXEC TransitiveMemberFindByGroupID @GroupID

	-- Delete memberships that are Groups
	DELETE	tm
	FROM	#TransitiveMember AS tm
	WHERE	tm.TargetTypeID = @TargetTypeGroup

	IF @PolicyGUID IS NULL
		SELECT * FROM #TransitiveMember AS tm
	ELSE
		SELECT * FROM #TransitiveMember AS tm
		WHERE EXISTS(
			SELECT pa.TargetTypeID,pa.TargetID,pa.GUID
			FROM PolicyApplies AS pa
			WHERE	tm.TargetTypeID = pa.TargetTypeID
			  AND	tm.TargetID = pa.TargetID
			  AND	pa.GUID = @PolicyGUID
			UNION
			SELECT m.TargetTypeID,m.TargetID,pa.GUID
			FROM PolicyApplies AS pa
			INNER JOIN Member m ON pa.TargetID = m.GroupID 
			WHERE	pa.TargetTypeID = 3
			  AND	tm.TargetTypeID = m.TargetTypeID
			  AND	tm.TargetID = m.TargetID
			  AND	pa.GUID = @PolicyGUID
		)
	DROP TABLE #TransitiveMember
GO

PRINT 'Creating procedure to get all members of a group, including members of child groups, with details'
IF EXISTS (
	SELECT * FROM dbo.sysobjects
	WHERE [name] = 'TransitiveMemberWithTargetGetAllByGroupIDPolicyGUID' AND xtype = 'P'
)
	DROP PROCEDURE TransitiveMemberWithTargetGetAllByGroupIDPolicyGUID
GO

CREATE PROCEDURE TransitiveMemberWithTargetGetAllByGroupIDPolicyGUID
	@GroupID	int,
	@PolicyGUID	binary(16) = NULL
AS
	DECLARE @TargetTypeGroup int
	SET @TargetTypeGroup = 3

	-- Set up the temporary table
	IF OBJECT_ID('tempdb..#TransitiveMember') IS NULL
		CREATE TABLE #TransitiveMember (
			GroupID			int NOT NULL,
			TargetTypeID		int NOT NULL,
			TargetID		int NOT NULL,
			MemberMode		int NOT NULL DEFAULT 1
		)
	EXEC TransitiveMemberFindByGroupID @GroupID

	-- Delete all memberships that are Groups
	DELETE	tm
	FROM	#TransitiveMember AS tm
	WHERE	tm.TargetTypeID = @TargetTypeGroup

	IF @PolicyGUID IS NOT NULL
		DELETE	tm
		FROM	#TransitiveMember AS tm
		WHERE NOT EXISTS(
			SELECT pa.TargetTypeID,pa.TargetID,pa.GUID
			FROM PolicyApplies AS pa
			WHERE	tm.TargetTypeID = pa.TargetTypeID
			  AND	tm.TargetID = pa.TargetID
			  AND	pa.GUID = @PolicyGUID
			UNION
			SELECT m.TargetTypeID,m.TargetID,pa.GUID
			FROM PolicyApplies AS pa
			INNER JOIN Member m ON pa.TargetID = m.GroupID 
			WHERE	pa.TargetTypeID = 3
			  AND	tm.TargetTypeID = m.TargetTypeID
			  AND	tm.TargetID = m.TargetID
			  AND	pa.GUID = @PolicyGUID
			)

	SELECT	tm.*,
		target.TargetCN,
		target.GUID AS TargetGUID,
		o.RDN AS OrganizationRDN,
		d.DN as DomainDN,
		o.OrganizationID
	FROM	#TransitiveMember AS tm,
		(SELECT	1 AS TargetTypeID,
			ComputerID as TargetID,
			ComputerCN as TargetCN,
			GUID,
			ComputerOUID AS OrganizationID
		 FROM	Computer
		UNION
		 SELECT	2 AS TargetTypeID,
		 	UserID as TargetID,
			UserCN as TargetCN,
			GUID,
			UserOUID AS OrganizationID
		 FROM	[User]
	--	UNION
	--	 SELECT	3 AS TargetTypeID, GroupID as TargetID, GroupCN AS TargetCN, GUID
	--	 FROM	[Group]
		) AS target,
		Organization as o,
		Domain as d
	WHERE	tm.TargetID = target.TargetID
	  AND	tm.TargetTypeID = target.TargetTypeID
	  AND	target.OrganizationID = o.OrganizationID
	  AND	o.DomainID = d.OrganizationID
	  
	DROP TABLE #TransitiveMember
GO

PRINT 'Creating procedure to get all denied members of a group, including members of child groups'
IF EXISTS (
	SELECT * FROM dbo.sysobjects
	WHERE [name] = 'TransitiveMemberDeniedGetAllByGroupID' AND xtype = 'P'
)
	DROP PROCEDURE TransitiveMemberDeniedGetAllByGroupID
GO

CREATE PROCEDURE TransitiveMemberDeniedGetAllByGroupID
	@GroupID	int
AS
	DECLARE @TargetTypeGroup int
	SET @TargetTypeGroup = 3

	-- Set up the temporary table
	IF OBJECT_ID('tempdb..#TransitiveMember') IS NULL
		CREATE TABLE #TransitiveMember (
			GroupID			int NOT NULL,
			TargetTypeID		int NOT NULL,
			TargetID		int NOT NULL,
			MemberMode		int NOT NULL DEFAULT 1
		)

	-- Calculate all denied members:
	EXEC TransitiveMemberFindByGroupID @GroupID, 2

	-- Select all memberships that aren't groups
	SELECT * FROM #TransitiveMember AS tm
	WHERE	tm.TargetTypeID <> @TargetTypeGroup
	DROP TABLE #TransitiveMember
GO

PRINT 'Creating procedure to count members of a group who will receive (or can''t receive) a package'
IF EXISTS (
	SELECT * FROM dbo.sysobjects
	WHERE [name] = 'TransitiveMemberCountAllocationByGroup' AND xtype = 'P'
)
	DROP PROCEDURE TransitiveMemberCountAllocationByGroup
GO
-- For a given Group and PackageAllocation, count how many of
-- the group members already have the package, can receive the
-- package, cannot receive the package because the policy
-- doesn't apply and are denied the package.
CREATE PROCEDURE TransitiveMemberCountAllocationByGroup
	@GroupID		int,		-- The Group we're analysing
	@PolicyGUID		binary(16),	-- The Policy
	@PackagePathID		int,		-- The PackagePath
	@TargetTypeID		int,		-- Users or Computers?
	@AllocationDetailsID	int		-- The AllocationDetails
AS

	-- Set up the temporary table
	IF OBJECT_ID('tempdb..#TransitiveMember') IS NULL
		CREATE TABLE #TransitiveMember (
			GroupID			int NOT NULL,
			TargetTypeID		int NOT NULL,
			TargetID		int NOT NULL,
			MemberMode		int NOT NULL DEFAULT 1
		)

	-- Calculate who's already allowed & denied this PackageAllocation
	IF OBJECT_ID('tempdb..#AccessGroup') IS NULL
		CREATE TABLE #AccessGroup (
			GroupID			int NOT NULL,
			TargetTypeID		int NOT NULL,
			TargetID		int NOT NULL,
			MemberMode		int NOT NULL DEFAULT 1
		)
	ELSE DELETE #AccessGroup

	DECLARE	@AccessGroupID	int
	SELECT	@AccessGroupID = AccessGroupID
	FROM	PackageAllocation
	WHERE	@PolicyGUID = PolicyGUID
	  AND	@PackagePathID = PackagePathID
	  AND	@TargetTypeID = TargetTypeID
	  AND	@AllocationDetailsID = AllocationDetailsID

	IF @AccessGroupID IS NULL
	OR (SELECT GroupID from [Group] where GroupID = @GroupID) IS NULL
	BEGIN	-- The Access Group doesn't exist
		SELECT -1 AS AppliesAlready, -1 AS CanAdd, -1 AS NotPolicy, -1 AS Denied
		RETURN
	END

	-- Get the list of those to who the package already applies
	EXEC TransitiveMemberFindByGroupID @AccessGroupID, 3
	INSERT #AccessGroup SELECT * FROM #TransitiveMember	-- Save results
	WHERE TargetTypeID < 3

	/* diagnostic code
	select	TargetTypeID,
		sum(CASE WHEN MemberMode = 0 THEN 1 ELSE 0 END) as DenyCount,
		sum(CASE WHEN MemberMode <> 0 THEN 1 ELSE 0 END) as AllowCount
	from #AccessGroup GROUP BY TargetTypeID
	*/

	-- Calculate who's allowed in the new group
	EXEC TransitiveMemberFindByGroupID @GroupID, 1
	DELETE #TransitiveMember WHERE TargetTypeID <> @TargetTypeID

	IF (SELECT count(*) FROM #TransitiveMember) = 0
	BEGIN		-- There are no relevant users/computers in the group
		SELECT 0 AS AppliesAlready, 0 AS CanAdd, 0 AS NotPolicy, 0 AS Denied
		RETURN
	END

	SELECT						-- For this user/computer:
		SUM(CASE WHEN pa.GUID IS NOT NULL	-- The Policy applies
				AND ag.MemberMode > 0	-- it's allowed the package
			THEN 1 ELSE 0 END
		) AS AppliesAlready,
		SUM(CASE WHEN pa.GUID IS NOT NULL	-- The Policy applies
				AND ag.MemberMode IS NULL -- Not in package group yet
				AND tm.MemberMode > 0	-- but, in candidate group
			THEN 1 ELSE 0 END
		) AS CanAdd,
		SUM(CASE WHEN pa.GUID IS NULL		-- The Policy doesn't apply
			THEN 1 ELSE 0 END
		) AS NotPolicy,
		SUM(CASE WHEN pa.GUID IS NOT NULL	-- The Policy applies, but
				AND ag.MemberMode = 0	-- Membership is denied
			THEN 1 ELSE 0 END
		) AS Denied
	FROM	#TransitiveMember as tm			-- Process all candidate members
		LEFT OUTER JOIN				-- with anything we can match
		#AccessGroup as ag			-- from the package group
			ON tm.TargetTypeID = ag.TargetTypeID
			AND tm.TargetID = ag.TargetID
		LEFT OUTER JOIN
		PolicyApplies as pa			-- and the PolicyApplies set
			ON tm.TargetTypeID = pa.TargetTypeID
			AND tm.TargetID = pa.TargetID
			AND pa.GUID = @PolicyGUID
GO


PRINT 'Creating procedure to get children by DomainDN and RDN'
IF EXISTS(SELECT * FROM sysobjects WHERE xtype = 'P'

            AND name = 'OrganizationGetChildrenByDomainDNRDN')

      DROP PROCEDURE OrganizationGetChildrenByDomainDNRDN

GO

CREATE PROCEDURE OrganizationGetChildrenByDomainDNRDN
            @DomainDN	nvarchar(100) = NULL,
            @RDN		nvarchar(400) = NULL
AS
BEGIN
	SELECT 
			o.*
	FROM	
			Domain AS d 
			
			JOIN Organization AS o
			ON 
				d.OrganizationID = o.DomainID
			
			JOIN Organization AS oParent
			ON
				oParent.RDN = @RDN
				AND	 
				o.DomainID = oParent.DomainID
    WHERE  
			d.DN = @DomainDN
            AND    
				RIGHT(o.RDN, LEN(oParent.RDN)) = oParent.RDN
            AND    
				o.OrganizationID <> oParent.OrganizationID
            AND    
				REPLACE(LEFT(o.RDN, LEN(o.RDN) - LEN(oParent.RDN) - 1), '\,', '') NOT LIKE '%,%'
    ORDER BY 
			o.RDNReverse
END
GO

IF EXISTS(SELECT * FROM sysobjects WHERE name = 'TableGetFromString')
            DROP FUNCTION TableGetFromString
GO

SET QUOTED_IDENTIFIER ON
GO
SET ANSI_NULLS ON
GO


CREATE FUNCTION dbo.TableGetFromString (@list nvarchar(max))
	RETURNS TABLE
AS

RETURN
	WITH strings AS
	(
		SELECT
			CASE WHEN CHARINDEX(' ', LTRIM(@list)) > 0 THEN SUBSTRING(LTRIM(@list), 1, CHARINDEX(' ', LTRIM(@list)) - 1) ELSE LTRIM(@list) END AS string,
			LTRIM(CASE WHEN CHARINDEX(' ', LTRIM(@list)) > 0 THEN SUBSTRING(LTRIM(@list), CHARINDEX(' ', LTRIM(@list)) + 1, LEN(LTRIM(@list))) ELSE '' END) AS remainder
		
		UNION ALL
		
		SELECT
			CASE WHEN CHARINDEX(' ', remainder) > 0 THEN SUBSTRING(remainder, 1, CHARINDEX(' ', remainder) - 1) ELSE remainder END AS string,
			LTRIM(CASE WHEN CHARINDEX(' ', remainder) > 0 THEN SUBSTRING(remainder, CHARINDEX(' ', remainder) + 1, LEN(remainder)) ELSE '' END)AS remainder
		FROM strings
		WHERE RTRIM(remainder) <> ''
	)

	SELECT
		string
	FROM strings
	WHERE @list IS NOT NULL
GO

--
-- Table function to split space delimted string of IDs into a table
--

IF EXISTS(SELECT * FROM sysobjects WHERE name = 'TableGetFromIntString')
            DROP FUNCTION TableGetFromIntString
GO

SET QUOTED_IDENTIFIER ON
GO
SET ANSI_NULLS ON
GO


CREATE FUNCTION dbo.TableGetFromIntString (@list ntext)
      RETURNS TABLE
AS

RETURN
	SELECT CONVERT(int, string) AS number
	FROM dbo.TableGetFromString(@list)
GO
PRINT 'Creating procedure to get domains given domain ids'
IF EXISTS(SELECT * FROM sysobjects WHERE xtype = 'P'

            AND name = 'DomainGetAllByManyIDs')

      DROP PROCEDURE DomainGetAllByManyIDs

GO

CREATE PROCEDURE DomainGetAllByManyIDs(@IdList ntext)
AS
BEGIN
	SELECT 	DISTINCT d.*
	FROM	Domain as d 
	JOIN	TableGetFromIntString(@IdList) ids ON d.OrganizationID = ids.number
END
GO


PRINT 'Creating procedure to get all policies and its domain details'
IF EXISTS(SELECT * FROM sysobjects WHERE xtype = 'P'

            AND name = 'PolicyInfoGetAll')

      DROP PROCEDURE PolicyInfoGetAll

GO

CREATE PROCEDURE PolicyInfoGetAll
AS
BEGIN
	SELECT 	p.GUID,
		p.DisplayName,
		p.DomainID,
		d.DN as DomainDN,		
		d.DomainType,
		p.EnabledForUsers,
		p.EnabledForComputers
	FROM	Policy as p 
	INNER JOIN domain as d 
		on d.OrganizationID = p.DomainID
	WHERE	p.GUID <> 0x31B2F340016D11D2945F00C04FB984F9 AND -- Ignore Default Domain Policy
			p.GUID <> 0x6AC1786C016F11D2945F00C04FB984F9 -- Ignore Default Domain Controllers Policy							
END
GO

PRINT 'Creating procedure to get all policies and its domain details, filtering on the name and version number of the packages linked to each policy'
IF EXISTS(SELECT * FROM sysobjects WHERE xtype = 'P'

            AND name = 'PolicyInfoGetAllByPackageFilterString')

      DROP PROCEDURE PolicyInfoGetAllByPackageFilterString

GO

CREATE PROCEDURE PolicyInfoGetAllByPackageFilterString
	@packageName		nvarchar(64) = '%',
	@versionNum		nvarchar(32) = '%'
AS
BEGIN
	SELECT 	DISTINCT
		p.GUID,
		p.DisplayName,
		p.DomainID,
		d.DN as DomainDN,		
		d.DomainType,
		p.EnabledForUsers,
		p.EnabledForComputers
	FROM	Policy as p 
	INNER JOIN domain as d 
		on d.OrganizationID = p.DomainID
	INNER JOIN PackageAllocation as pa
		on pa.PolicyGUID = p.GUID
	INNER JOIN PackageVersion as pv
		on pv.PackagePathID = pa.PackagePathID
	INNER JOIN MediaContainsPackageVersion as mcpv
		ON mcpv.PackageVersionID = pv.PackageVersionID AND mcpv.MediaID = 1
	WHERE	p.GUID <> 0x31B2F340016D11D2945F00C04FB984F9 AND -- Ignore Default Domain Policy
		p.GUID <> 0x6AC1786C016F11D2945F00C04FB984F9 AND -- Ignore Default Domain Controllers Policy						
		pv.Title LIKE '%' + @packageName + '%' AND
		pv.Version LIKE '%' + @versionNum + '%'
END
GO



PRINT 'Creating procedure to get all packages and their policies GUIDs, filtering on the name and version number of the packages'
IF EXISTS(SELECT * FROM sysobjects WHERE xtype = 'P'

            AND name = 'PolicyPackageInfoGetAll')

      DROP PROCEDURE PolicyPackageInfoGetAll

GO

CREATE PROCEDURE PolicyPackageInfoGetAll
	@packageName		nvarchar(64) = '%',
	@versionNum		nvarchar(32) = '%'
AS
BEGIN
SELECT DISTINCT
	p.GUID as PolicyGUID,
	pv.Title as PackageName,
	pv.Version as PackageVersion,
	pa.PackagePathID,
	pp.PackagePathTypeID,
	pp.PackageFullName as PackagePath,
	CASE WHEN auth.PackagePathID is NULL THEN CAST(1 as bit) ELSE CAST(0 as bit) END as SecurityFiltered,
	ad.Action,
	pa.Precedence as InstallationOrder,
	pa.TargetTypeID,
	pa.AllocationDetailsID
FROM Policy as p
        INNER JOIN PackageAllocation as pa
                ON pa.PolicyGUID = p.GUID
        INNER JOIN PackageVersion as pv
                ON pv.PackagePathID = pa.PackagePathID
	INNER JOIN MediaContainsPackageVersion as mcpv
		ON mcpv.PackageVersionID = pv.PackageVersionID AND mcpv.MediaID = 1
        INNER JOIN PackagePath as pp
                ON pp.PackagePathID = pa.PackagePathID
        INNER JOIN AllocationDetails as ad
                ON ad.AllocationDetailsID = pa.AllocationDetailsID
        LEFT OUTER JOIN (
                SELECT  authUserMembers.PackagePathID,
						authUserMembers.TargetTypeID
                FROM
                        (
                                SELECT  count(*) as PackageCount,
                                                p.GUID,
                                                pa.PackagePathID,
						pa.TargetTypeID
                                FROM    Policy as p
                                INNER JOIN PackageAllocation as pa
                                        ON pa.PolicyGUID = p.GUID
                                INNER JOIN Member as m
                                        ON m.GroupID = pa.AccessGroupID
                                GROUP BY p.GUID, pa.PackagePathID, pa.TargetTypeID
                        ) as packageCount
                        INNER JOIN
                        (
                                SELECT  p.GUID,
                                        pa.PackagePathID,
					pa.TargetTypeID
                                FROM    Policy as p
                                INNER JOIN PackageAllocation as pa
                                        ON pa.PolicyGUID = p.GUID
                                INNER JOIN Member as m
                                        ON m.GroupID = pa.AccessGroupID
                                WHERE   m.TargetTypeID = 3      -- Group
                                  AND   m.TargetID = 1          -- Authenticated Users
                                  AND   m.MemberMode = 1  -- Allowed
                        ) as authUserMembers
                        ON      packageCount.GUID = authUserMembers.GUID
                        AND     packageCount.PackagePathID = authUserMembers.PackagePathID
			AND	packageCount.TargetTypeID = authUserMembers.TargetTypeID
                        WHERE   packageCount.PackageCount = 1
        ) as auth 
			on	auth.PackagePathID = pa.PackagePathID 
			AND	auth.TargetTypeID = pa.TargetTypeID
WHERE
	pv.Title LIKE '%' + @packageName + '%' AND
	pv.Version LIKE '%' + @versionNum + '%'
END
GO


PRINT 'Creating procedure to remove schedule by policy guid and TargetTypeID'
IF EXISTS(SELECT * FROM sysobjects WHERE xtype = 'P'

            AND name = 'PackageAllocationRemoveAllSchedulesByPolicyGUIDTargetTypeID')

      DROP PROCEDURE PackageAllocationRemoveAllSchedulesByPolicyGUIDTargetTypeID

GO

CREATE PROCEDURE PackageAllocationRemoveAllSchedulesByPolicyGUIDTargetTypeID
	@PolicyGUID binary(16),
	@TargetTypeID int
AS
BEGIN
	DELETE PackageAllocation From PackageAllocation
	INNER JOIN PackagePath on PackagePath.PackagePathID = PackageAllocation.PackagePathID
	WHERE PackageAllocation.PolicyGUID = @PolicyGUID
	    AND PackageAllocation.TargetTypeID = @TargetTypeID
	    AND	PackagePath.PackagePathTypeID IN (3,4) -- 3 = Legacy Schedule, 4 = Schedule
END
GO

PRINT 'Creating procedure to get next precedence sequence for a given PolicyGUID and TargetTypeID and PackagePathTypeID'
IF EXISTS(SELECT * FROM sysobjects WHERE xtype = 'P'

            AND name = 'PackageAllocationGetNextPrecedenceByPolicyGUIDTargetTypeIDPackagePathTypeID')

      DROP PROCEDURE PackageAllocationGetNextPrecedenceByPolicyGUIDTargetTypeIDPackagePathTypeID

GO

CREATE PROCEDURE PackageAllocationGetNextPrecedenceByPolicyGUIDTargetTypeIDPackagePathTypeID
        @PolicyGUID binary(16),
        @TargetTypeID int,
        @PackagePathTypeID int
AS
BEGIN
	DECLARE @GetPrecedenceAfterMDConfig bit

	IF (@PackagePathTypeID IN (3,4,5))
	    SET @GetPrecedenceAfterMDConfig = 1
	ELSE
	    SET @GetPrecedenceAfterMDConfig = 0
	
	SELECT (CASE WHEN MAX(Precedence) IS NULL THEN 1 ELSE MAX(Precedence) + 1 END)  as NextPrecedence
	FROM   PackageAllocation
	    INNER JOIN PackagePath on PackagePath.PackagePathID = PackageAllocation.PackagePathID
	WHERE PackageAllocation.PolicyGUID = @PolicyGUID
	    AND PackageAllocation.TargetTypeID = @TargetTypeID
   	    AND (
		@GetPrecedenceAfterMDConfig = 0	
		OR (@GetPrecedenceAfterMDConfig = 1 AND PackagePath.PackagePathTypeID = 5)
		
	    )
END
GO

PRINT 'Creating procedure to get increment precedence by incremented value'
IF EXISTS(SELECT * FROM sysobjects WHERE xtype = 'P'

            AND name = 'PackageAllocationIncrementPrecedenceByPolicyGUIDTargetTypeID')

      DROP PROCEDURE PackageAllocationIncrementPrecedenceByPolicyGUIDTargetTypeID

GO

CREATE PROCEDURE PackageAllocationIncrementPrecedenceByPolicyGUIDTargetTypeID
        @PolicyGUID binary(16),
        @TargetTypeID int,
        @StartFromPrecedence int,
	@IncrementedValue int
AS
BEGIN
	UPDATE PackageAllocation 
	    SET Precedence = pa.Precedence + @IncrementedValue
	FROM PackageAllocation as pa
	WHERE pa.PolicyGUID = @PolicyGUID
	    AND pa.TargetTypeID = @TargetTypeID
	    AND pa.Precedence >= @StartFromPrecedence
END
GO

PRINT 'Creating procedure to get decrement precedence by decremented value'
IF EXISTS(SELECT * FROM sysobjects WHERE xtype = 'P'

            AND name = 'PackageAllocationDecrementPrecedenceByPolicyGUIDTargetTypeID')

      DROP PROCEDURE PackageAllocationDecrementPrecedenceByPolicyGUIDTargetTypeID

GO

CREATE PROCEDURE PackageAllocationDecrementPrecedenceByPolicyGUIDTargetTypeID
        @PolicyGUID binary(16),
        @TargetTypeID int,
        @StartFromPrecedence int,
	@DecrementedValue int
AS
BEGIN
	UPDATE PackageAllocation 
	    SET Precedence = pa.Precedence - @DecrementedValue
	FROM PackageAllocation as pa
	WHERE pa.PolicyGUID = @PolicyGUID
	    AND pa.TargetTypeID = @TargetTypeID
	    AND pa.Precedence > @StartFromPrecedence
END
GO

PRINT 'Creating procedure to get Policy Name and its domain'
IF EXISTS(SELECT * FROM sysobjects WHERE xtype = 'P'

            AND name = 'PolicyNameAndDomainGetAllByDomainType')

      DROP PROCEDURE PolicyNameAndDomainGetAllByDomainType
GO

CREATE PROCEDURE PolicyNameAndDomainGetAllByDomainType
		@DomainType varchar(4) 
AS
BEGIN
	SELECT 
			p.GUID,
			p.DisplayName AS PolicyName,
			d.DN AS DomainName
	FROM Policy as p
	INNER JOIN Domain as d on d.OrganizationID = p.DomainID
	WHERE d.DomainType = @DomainType
END
GO
/*
 * $Id: Allocation.sql 84480 2007-07-24 06:34:27Z pca $
 *
 * Customised procedures to use in allocation operations
 *
 * Protected by US patent 6,006,034; patents pending.
 * Copyright 2000-2003 ManageSoft Corporation. All rights reserved.
 * Reproduction, adaptation, or translation without prior permission
 * is prohibited.
 */
-- USE ManageSoft
GO
PRINT 'Creating procedure to retrieve targeted a package record from the view'
IF EXISTS(SELECT * FROM sysobjects WHERE xtype = 'P'
        AND [name] = 'TargetedPackageGetByTargetOUIDTargetTypeIDTargetIDPackagePathIDPolicyGUID'
)
        DROP PROCEDURE TargetedPackageGetByTargetOUIDTargetTypeIDTargetIDPackagePathIDPolicyGUID
GO
CREATE PROCEDURE TargetedPackageGetByTargetOUIDTargetTypeIDTargetIDPackagePathIDPolicyGUID
	@TargetOUID int,
	@TargetTypeID int,
	@TargetID int,
	@PackagePathID int,
	@PolicyGUID int
AS
	SELECT
		CASE WHEN pa.TargetTypeID = 3 THEN m.TargetTypeID ELSE pa.TargetTypeID END AS TargetTypeID,
		CASE WHEN pa.TargetTypeID = 3 THEN
				CASE WHEN m.TargetTypeID = 1 THEN c.ComputerOUID ELSE u.UserOUID END
			ELSE
				pa.TargetOUID
		END AS TargetOUID,
		CASE WHEN pa.TargetTypeID = 3 THEN m.TargetID ELSE pa.TargetID END AS TargetID,
		pa.PackagePathID,
		pa.PolicyGUID,
		pa.AllocationDetailsID,
		ip.PostponePeriodStart,
		pa.Precedence, 
		pa.PolicyVersion,
		CASE WHEN pa.TargetTypeID = 3 THEN 1 ELSE 0 END AS FromRSOP,
		CASE WHEN pa.TargetTypeID = 3 THEN pa.TargetID ELSE NULL END AS RSOPGroupID
	FROM	PackageApplies AS pa
	INNER JOIN AllocationDetails AS ad
		ON pa.AllocationDetailsID = ad.AllocationDetailsID
	LEFT OUTER JOIN Member AS m
		ON pa.TargetTypeID = 3 -- RSOP Groups
		AND m.GroupID = pa.TargetID
		AND m.TargetTypeID = @TargetTypeID
	LEFT OUTER JOIN Computer AS c
		ON m.TargetTypeID = 1
		AND m.TargetID = c.ComputerID
		AND c.ComputerOUID = @TargetOUID
	LEFT OUTER JOIN [User] AS u
		ON m.TargetTypeID = 2
		AND m.TargetID = u.UserID
		AND u.UserOUID = @TargetOUID
	LEFT OUTER JOIN InstallationPostponement AS ip
		ON ip.PackagePathID = pa.PackagePathID
		AND ip.PolicyGUID = pa.PolicyGUID
		AND ip.AllocationDetailsID = pa.AllocationDetailsID
		AND ((
			ip.TargetTypeID = pa.TargetTypeID
		) OR (
			pa.TargetTypeID = 3 AND ip.TargetTypeID = m.TargetTypeID
		))
		AND ((
			ip.TargetID = pa.TargetID
		) OR (
			pa.TargetID = 3 AND ip.TargetID = m.TargetID
		))
	WHERE
		pa.PackagePathID = @PackagePathID
		AND pa.PolicyGUID = @PolicyGUID
		AND ((
			pa.TargetTypeID = @TargetTypeID OR pa.TargetTypeID = 3
		) AND (
			pa.TargetTypeID <> 3 AND pa.TargetOUID = @TargetOUID
		))
GO

PRINT 'Creating procedure to check whether a package can be added to policy'
IF EXISTS(SELECT * FROM sysobjects WHERE xtype = 'P'
        AND [name] = 'CanAddPackageToPolicy'
)
        DROP PROCEDURE CanAddPackageToPolicy
GO
CREATE PROCEDURE CanAddPackageToPolicy
	@PackageFullName nvarchar(256)
AS
	SELECT TOP 1 ps.CanAddToPolicy, ps.[Name] 
	FROM PackagePath pp
	INNER JOIN PackageVersion pv ON pp.PackagePathID = pv.PackagePathID
	INNER JOIN PackageVersionInState pvs ON pv.PackageVersionID = pvs.PackageVersionID
	INNER JOIN PackageState ps ON pvs.PackageStateID = ps.PackageStateID
	WHERE pp.PackageFullName = REPLACE(@PackageFullName,'\','/')
	ORDER BY pvs.Changed DESC
GO
/*
 * $Id: Populate.sql 95576 2010-01-21 02:54:16Z rlowery $
 *
 * Procedures that assist in populating data in the database,
 * especially when upgrading from earlier versions.
 *
 * Protected by US patent 6,006,034; patents pending.
 * Copyright 2000-2002 ManageSoft Corporation. All rights reserved.
 * Reproduction, adaptation, or translation without prior permission
 * is prohibited.
 */
-- USE ManageSoft
GO

PRINT 'Creating procedure to populate missing Organizations from AD'
IF EXISTS(SELECT * FROM sysobjects WHERE xtype = 'P'
	AND name = 'PopulateMissingOUs'
)
	DROP PROCEDURE PopulateMissingOUs
GO
CREATE PROCEDURE PopulateMissingOUs
AS
	INSERT INTO Organization (DomainID, RDN, GUID, BlockInheritance)
		SELECT	DomainID, RDN, GUID, BlockInheritance
		FROM	ADSDOU AS ads
		WHERE NOT EXISTS	-- RDN and GUID don't exist already
			(SELECT * FROM Organization AS o
				WHERE ads.RDN = o.RDN OR ads.GUID = o.GUID )

	DECLARE @count int
	SET @count = @@ROWCOUNT

	-- Drop a message in the Windows Application log
	IF (@count <> 0)
	BEGIN
		DECLARE @msg varchar(256)
		SET @msg = 'ManageSoft: Populated '+STR(@count, 7)+
			' missing OrganizationalUnits into SQL'
		PRINT @msg
	END
GO

PRINT 'Creating procedure to populate the Organization.GUID column'
IF EXISTS(SELECT * FROM sysobjects WHERE xtype = 'P'
	AND name = 'PopulateOrganizationGUIDs'
)
	DROP PROCEDURE PopulateOrganizationGUIDs
GO
CREATE PROCEDURE PopulateOrganizationGUIDs
AS
	UPDATE Organization
		SET GUID = ads.GUID
		FROM ADSDOU AS ads
		WHERE Organization.DomainID = ads.DomainID
		  AND Organization.RDN = ads.RDN
		  AND Organization.GUID IS NULL
		  AND NOT EXISTS	-- GUID isn't already attached to an OU
		  	(SELECT * FROM Organization AS o
				WHERE o.GUID = ads.GUID)

	DECLARE @count int
	SET @count = @@ROWCOUNT

	-- Drop a message in the Windows Application log
	IF (@count <> 0)
	BEGIN
		DECLARE @msg varchar(256)
		SET @msg = 'Populated '+STR(@count, 7)+
			' missing OrganizationalUnit GUIDs into SQL'
		PRINT @msg
	END
GO

PRINT 'Creating procedure to populate the Computer.GUID column'
IF EXISTS(SELECT * FROM sysobjects WHERE xtype = 'P'
	AND name = 'PopulateComputerGUIDs'
)
	DROP PROCEDURE PopulateComputerGUIDs
GO
CREATE PROCEDURE PopulateComputerGUIDs
AS
	UPDATE Computer
		SET GUID = adc.GUID
		FROM Organization AS o, ADComputer AS adc
		WHERE adc.ComputerCN = Computer.ComputerCN
		  AND adc.ComputerOURDN = o.RDN
		  AND adc.DomainID = o.DomainID
		  AND Computer.ComputerOUID = o.OrganizationID
		  AND Computer.GUID IS NULL
		  AND NOT EXISTS	-- GUID isn't already attached
		  	(SELECT * FROM Computer AS c WHERE c.GUID = adc.GUID)

	DECLARE @count int
	SET @count = @@ROWCOUNT

	-- Drop a message in the Windows Application log
	IF (@count <> 0)
	BEGIN
		DECLARE @msg varchar(256)
		SET @msg = 'Populated '+STR(@count, 7)+
			' missing Computer GUIDs into SQL'
		PRINT @msg
	END
GO

PRINT 'Creating procedure to populate the User.GUID column'
IF EXISTS(SELECT * FROM sysobjects WHERE xtype = 'P'
	AND name = 'PopulateUserGUIDs'
)
	DROP PROCEDURE PopulateUserGUIDs
GO
CREATE PROCEDURE PopulateUserGUIDs
AS
	UPDATE [User]
		SET GUID = adu.GUID
		FROM Organization AS o, ADUser AS adu
		WHERE adu.UserCN = [User].UserCN
		  AND adu.UserOURDN = o.RDN
		  AND adu.DomainID = o.DomainID
		  AND [User].UserOUID = o.OrganizationID
		  AND [User].GUID IS NULL
		  AND NOT EXISTS	-- GUID isn't already attached
		  	(SELECT * FROM [User] AS u WHERE u.GUID = adu.GUID)

	DECLARE @count int
	SET @count = @@ROWCOUNT

	-- Drop a message in the Windows Application log
	IF (@count <> 0)
	BEGIN
		DECLARE @msg varchar(256)
		SET @msg = 'Populated '+STR(@count, 7)+
			' missing User GUIDs into SQL'
		PRINT @msg
	END
GO

PRINT 'Creating procedure to fix denormalised OU references'
IF EXISTS(SELECT * FROM sysobjects WHERE xtype = 'P'
	AND name = 'FixOUReferences'
)
	DROP PROCEDURE FixOUReferences
GO
CREATE PROCEDURE FixOUReferences
AS
	DECLARE @msg varchar(2304)
	SET @msg = 'Fixing denormalised OU References'
	PRINT @msg

	UPDATE Installation
		SET OrganizationID = CASE WHEN Installation.UserID = 1
					THEN c.ComputerOUID
					ELSE u.UserOUID
				END
		FROM [User] AS u, Computer AS c
		WHERE Installation.UserID = u.UserID
		  AND Installation.ComputerID = c.ComputerID
		  AND Installation.OrganizationID <> CASE
					WHEN Installation.UserID = 1
					THEN c.ComputerOUID
					ELSE u.UserOUID
				END

	UPDATE PackageApplies
		SET TargetOUID = CASE WHEN TargetTypeID = 1
					THEN c.ComputerOUID
					ELSE u.UserOUID
				END
		FROM [User] AS u, Computer AS c
		WHERE (PackageApplies.TargetTypeID = 1
			AND PackageApplies.TargetID = c.ComputerID)
		   OR (PackageApplies.TargetTypeID = 2
		   	AND PackageApplies.TargetID = u.UserID) 
GO

PRINT 'Creating procedure to populate missing organization units for a domain'
IF EXISTS(SELECT * FROM sysobjects WHERE xtype = 'P'
	AND name = 'DomainOrganizationPopulate'
)
	DROP PROCEDURE DomainOrganizationPopulate
GO
CREATE PROCEDURE DomainOrganizationPopulate
	@DomainID	int
AS
	INSERT INTO Organization (RDN, GUID, DomainID, BlockInheritance)
		SELECT	RDN, GUID, @DomainID, BlockInheritance
		FROM ADSDOU AS ao
		WHERE DomainID = @DomainID
		  AND NOT EXISTS(
			SELECT * FROM Organization AS o
			WHERE o.RDN = ao.RDN
			   OR o.GUID = ao.GUID
		)
GO

PRINT 'Creating procedure to populate missing computers for a domain'
IF EXISTS(SELECT * FROM sysobjects WHERE xtype = 'P'
	AND name = 'DomainComputerPopulate'
)
	DROP PROCEDURE DomainComputerPopulate
GO
CREATE PROCEDURE DomainComputerPopulate
	@DomainID	int
AS
	INSERT INTO Computer (ComputerOUID, ComputerCN, GUID)
		SELECT	o.OrganizationID,
			ac.ComputerCN,
			ac.GUID 
		FROM	ADComputer AS ac,
			Organization AS o
		WHERE	ac.DomainID = @DomainID
		  AND	o.DomainID = @DomainID
		  AND	o.RDN = ac.ComputerOURDN
		  AND NOT EXISTS(
			-- GUID is unique in the whole database
		  	SELECT	*
			FROM	Computer AS c
			WHERE	c.GUID = ac.GUID 
		  )
		  AND NOT EXISTS(
			-- ComputerCN is unique in Organization
		  	SELECT	*
			FROM	Computer AS c
			WHERE	c.ComputerCN = ac.ComputerCN
				AND c.ComputerOUID = o.OrganizationID
		  )
  		  AND NOT EXISTS(
			-- ComputerCN is unique in Unknown OU
		  	SELECT	*
			FROM	Computer AS c,
					Organization AS co
			WHERE	c.ComputerCN = ac.ComputerCN
				AND c.ComputerOUID = co.OrganizationID
				AND co.DomainID = @DomainID
				AND co.IsUnknown = 1
		  )
GO

PRINT 'Creating procedure to populate missing users for a domain'
IF EXISTS(SELECT * FROM sysobjects WHERE xtype = 'P'
	AND name = 'DomainUserPopulate'
)
	DROP PROCEDURE DomainUserPopulate
GO
CREATE PROCEDURE DomainUserPopulate
	@DomainID	int
AS
	INSERT INTO [User] (UserOUID, UserCN, GUID, SAMAccountName)
		SELECT	o.OrganizationID,
			au.UserCN,
 			au.GUID, 
			au.SAMAccountName
		FROM	ADUser AS au,
			Organization as o
		WHERE	au.DomainID = @DomainID
		  AND	o.DomainID = @DomainID
		  AND	o.RDN = au.UserOURDN
		  AND NOT EXISTS(
			-- GUID is unique in the whole database
		  	SELECT	*
			FROM	[User] AS u
			WHERE	u.GUID = au.GUID
		  )
		  AND NOT EXISTS(
			-- SAMAccountName is unique in Domain
		  	SELECT	*
			FROM	[User] AS u
				INNER JOIN Organization AS uo
					ON uo.OrganizationID = u.UserOUID
			WHERE	u.SAMAccountName = au.SAMAccountName
				AND uo.DomainID = @DomainID
		  )
		  AND NOT EXISTS(
			-- UserCN is unique in OrganizationID
		  	SELECT	*
			FROM	[User] AS u
			WHERE	u.UserCN = au.UserCN
				AND u.UserOUID = o.OrganizationID
		  )
   		  AND NOT EXISTS(
			-- UserCN is unique in Unknown OU
		  	SELECT	*
			FROM	[User] AS u,
					Organization AS uo
			WHERE	u.UserCN = au.UserCN
				AND u.UserOUID = uo.OrganizationID
				AND uo.DomainID = @DomainID
				AND uo.IsUnknown = 1
		  )
GO
/*
 * $Id: OperatingSystem.sql 53886 2004-02-23 07:11:21Z cjh $
 *
 * Procedures to deal with the OperatingSystem classification hierarchy.
 *
 * Protected by US patent 6,006,034; patents pending.
 * Copyright 2000-2002 ManageSoft Corporation. All rights reserved.
 * Reproduction, adaptation, or translation without prior permission
 * is prohibited.
 */
-- USE ManageSoft
GO

IF EXISTS (
	SELECT * FROM dbo.sysobjects
	WHERE [name] = 'OperatingSystemBind' AND xtype = 'P'
)
	DROP PROCEDURE OperatingSystemBind
GO

CREATE PROCEDURE OperatingSystemBind
	@OperatingSystemName varchar(128)
AS
	DECLARE @OperatingSystemID AS INT

	SELECT @OperatingSystemID = OperatingSystemID
	FROM OperatingSystem
	WHERE OperatingSystemName = @OperatingSystemName

	IF @OperatingSystemID IS NULL
	BEGIN
		INSERT OperatingSystem (OperatingSystemName)
			VALUES (@OperatingSystemName)

		SELECT @OperatingSystemID = OperatingSystemID
		FROM OperatingSystem
		WHERE OperatingSystemName = @OperatingSystemName
	END

	RETURN @OperatingSystemID
GO

IF EXISTS (
	SELECT * FROM dbo.sysobjects
	WHERE [name] = 'ComputerUpdateOperatingSystemBound' AND xtype = 'P'
)
	DROP PROCEDURE ComputerUpdateOperatingSystemBound
GO

CREATE PROCEDURE ComputerUpdateOperatingSystemBound
	@ComputerID int,
	@OperatingSystemName varchar(128)
AS
	DECLARE @OperatingSystemID AS INT
	EXEC @OperatingSystemID = OperatingSystemBind @OperatingSystemName

	UPDATE Computer
	SET OperatingSystemID = @OperatingSystemID
	WHERE ComputerID = @ComputerID
GO

IF EXISTS (
	SELECT * FROM dbo.sysobjects
	WHERE [name] = 'OperatingSystemCategoryTest' AND xtype = 'P'
)
	DROP PROCEDURE OperatingSystemCategoryTest
GO
CREATE PROCEDURE OperatingSystemCategoryTest
	@CategoryID int,
	@OperatingSystemID int
AS
	WHILE @OperatingSystemID IS NOT NULL
	BEGIN
		IF @OperatingSystemID = @CategoryID
			RETURN 1
		SELECT @OperatingSystemID = Category
		FROM OperatingSystem
		WHERE @OperatingSystemID = OperatingSystemID
	END
	RETURN 0
GO
/*
 * $Id: CachePackage.sql 90026 2008-10-29 00:58:01Z pca $
 *
 * Procedures to repair lost Installation records from the Inventory
 * from the ManageSoft client application cache.
 *
 * When the T-R runs and finds software inventory from the ManageSoft
 * cache, it inserts the records into a temporary table and reconciles
 * those against the Installation.
 *
 * If we create the temporary table inside a stored procedure, that gets
 * dropped when the SP returns. If instead we create a global-temporary
 * table, we might collide with another T-R running at the same time.
 * Because we don't want schema details embedded into the PERL code, we
 * use a stored procedure to return the text of the required CREATE
 * TABLE command, which the T-R Perl code executes as dynamic SQL.
 *
 * Protected by US patent 6,006,034; patents pending.
 * Copyright 2000-2002 ManageSoft Corporation. All rights reserved.
 * Reproduction, adaptation, or translation without prior permission
 * is prohibited.
 */

-- USE ManageSoft
GO

IF EXISTS (
        SELECT * FROM dbo.sysobjects
        WHERE [name] = 'CachePackageSchema' AND xtype = 'P'
)
        DROP PROCEDURE CachePackageSchema
GO

CREATE PROCEDURE CachePackageSchema
AS
	SELECT
	'CREATE TABLE #CachePackage ('+
	'	ComputerID int NOT NULL, '+
	'	UserID int NOT NULL, '+
	'	PackageName varchar(64) COLLATE database_default NOT NULL, '+
	'	Version varchar(32) COLLATE database_default NOT NULL, '+
	'	Reported datetime, '+
	'	Action varchar(10) COLLATE database_default NOT NULL '+
	')' AS SQL
GO

IF EXISTS (
        SELECT * FROM dbo.sysobjects
        WHERE [name] = 'CachePackageInsert' AND xtype = 'P'
)
        DROP PROCEDURE CachePackageInsert
GO

CREATE PROCEDURE CachePackageInsert
	@ComputerID int,		-- The Computer
	@UserID int,			-- The User (or 1 for SYSTEM)
	@Reported datetime,		-- Date/Time of inventory
	@PackageName varchar(64),	-- The package name
	@Version varchar(32),		-- The package version
	@Action varchar(10)		-- The action taken 
AS
	INSERT INTO #CachePackage
		(ComputerID, UserID, Reported, PackageName, Version, Action)
		VALUES
		(@ComputerID, @UserID, @Reported, @PackageName, @Version, @Action)
GO

IF EXISTS (
        SELECT * FROM dbo.sysobjects
        WHERE [name] = 'CachePackageSync' AND xtype = 'P'
)
        DROP PROCEDURE CachePackageSync
GO

CREATE PROCEDURE CachePackageSync
	@InvType varchar(32)	-- "Full" or "Difference"
AS
	DECLARE @ComputerID int, @UserID int, @OUID int, @SWDate datetime
	SELECT TOP 1
		@ComputerID = ComputerID, @UserID = UserID
		FROM #CachePackage

	-- To insert a record, we need the User's or Computer's OUID:
	IF (@UserID <> 1)
		SELECT @OUID = UserOUID FROM [User]
			WHERE UserID = @UserID
	ELSE
		SELECT @OUID = ComputerOUID FROM Computer
			WHERE ComputerID = @ComputerID

	SELECT @SWDate = SWDate FROM InventoryReport
		WHERE ComputerID = @ComputerID
		  AND UserID = @UserID

	-- Delete failures that are replaced by inventory records here:
	-- The version comparison isn't the full N,N,N,N thing here but
	-- we can't be sure that's the format anyhow. The main thing is
	-- to ensure that exactly-matching Version numbers get deleted or
	-- we'll get a key uniqueness violation below.
	DELETE Installation
		FROM #CachePackage as c, PackageVersion AS v, PackageFamily AS f
		WHERE Installation.ComputerID = @ComputerID
		  AND Installation.UserID = @UserID
		  AND Installation.Result <> 'success'
		  AND Installation.Result <> 'rebootrequired'
		  AND f.PackageName = c.PackageName
		  AND v.Version <= c.Version
		  AND Installation.PackageVersionID = v.PackageVersionID
		  AND v.PackageFamilyID = f.PackageFamilyID

	-- Populate new PackageFamily entries
	INSERT PackageFamily (PackageName)
		SELECT DISTINCT cp.PackageName
		FROM	#CachePackage AS cp
		WHERE NOT EXISTS(
			SELECT * FROM PackageFamily AS pf
			WHERE cp.PackageName = pf.PackageName
		)

	-- Populate new PackageVersion entries.
	-- If a PackageVersion exists which has a matching FamilyName but
	-- not the matching version, we'll create a new PackageVersion with
	-- the same path. Otherwise since we don't have a Path value, we
	-- fabricate one as "Installed/PackageName", to ensure PV uniqueness.
	-- We should prefer a PackageVersion which is in the warehouse, but
	-- for now we just choose the first.

	DECLARE pvCursor CURSOR FOR
		SELECT DISTINCT
			cp.PackageName,
			cp.Version,
			(SELECT	TOP 1 PackageFullName
			 FROM	PackageVersion AS cpv,	-- Warehouse pkg version
			 	MediaContainsPackageVersion AS mcpv,
			 	PackagePath AS pp
			 WHERE	pf.PackageFamilyID = cpv.PackageFamilyID
			   AND	cpv.PackageVersionID = mcpv.PackageVersionID
			   AND	mcpv.MediaID = 1	-- Warehouse Media
			   AND	cpv.PackagePathID = pp.PackagePathID
			),
			(SELECT	TOP 1		-- Just get the highest-numbered
				PackageFullName
			 FROM	PackageVersion AS cpv,	-- Any pkg version
			 	PackagePath AS pp
			 WHERE	pf.PackageFamilyID = cpv.PackageFamilyID
			   AND	cpv.PackagePathID = pp.PackagePathID
			 ORDER BY cpv.Version DESC
			)
		FROM	#CachePackage AS cp,
			PackageFamily AS pf
		WHERE	cp.PackageName = pf.PackageName
		  AND	NOT EXISTS (	-- a PV with matching Family and version
				SELECT	*
				FROM	PackageVersion AS v
				WHERE	cp.Version = v.Version
				  AND	pf.PackageFamilyID = v.PackageFamilyID
			)

	DECLARE @cName varchar(64)
	DECLARE @cVersion varchar(32)
	DECLARE @cWarehouseFullname nvarchar(256)
	DECLARE @cFullname nvarchar(256)
	OPEN pvCursor
	FETCH NEXT FROM pvCursor INTO @cName, @cVersion, @cWarehouseFullname, @cFullname
	WHILE @@FETCH_STATUS = 0
	BEGIN
		IF @cWarehouseFullname IS NULL
			-- PackageFamily has no warehouse version
			IF @cFullname IS NOT NULL
				SET @cWarehouseFullname = @cFullname
			ELSE
				-- PackageFamily has no known version, pretend
				SET @cWarehouseFullname = 'Installed/'+@cName
		EXEC PackageVersionAddBound
			@cWarehouseFullname,	-- PackagePath
			@cVersion,		-- Version
			'',			-- Update
			@cName			-- PackageName
		FETCH NEXT FROM pvCursor INTO @cName, @cVersion, @cWarehouseFullname, @cFullname
	END
	CLOSE pvCursor
	DEALLOCATE pvCursor

	-- Join the cache inventory table and the Installation tables
	DECLARE @Changes int
	SELECT @Changes = 0
	-- New PackageName, Version and Reported-date
	DECLARE @cPN varchar(64), @cV varchar(32), @cPV int, @cRep datetime, @cAct varchar(10)
	-- Old PackageName, Version and Reported
	DECLARE @iPN varchar(64), @iV varchar(32), @iPV int, @iRep datetime
	DECLARE @Action varchar(10)

	DECLARE cp CURSOR FOR
		SELECT c.PackageName, c.Version, c.PackageVersionID, c.Reported, c.Action,
		       i.PackageName, i.Version, i.PackageVersionID, i.Reported
		FROM (
			SELECT	cp.PackageName AS PackageName,
				cp.Version AS Version,
				v.PackageVersionID AS PackageVersionID,
				cp.Reported AS Reported,
				cp.Action AS Action
			FROM #CachePackage as cp,
			     PackageVersion AS v, PackageFamily AS f
			WHERE f.PackageName = cp.PackageName
			  AND v.Version = cp.Version
			  AND v.PackageFamilyID = f.PackageFamilyID
		) AS c
		FULL OUTER JOIN (
			SELECT	f.PackageName AS PackageName,
				v.Version AS Version,
				v.PackageVersionID AS PackageVersionID,
				inst.Reported AS Reported
			FROM Installation as inst,
			     PackageVersion AS v, PackageFamily AS f
			WHERE inst.ComputerID = @ComputerID
			  AND inst.UserID = @UserID
			  AND inst.Result IN ('success', 'rebootrequired')
			  AND inst.PackageVersionID = v.PackageVersionID
			  AND v.PackageFamilyID = f.PackageFamilyID
		) AS i
		ON c.PackageName = i.PackageName
		WHERE c.Reported > i.Reported
		   OR i.Reported IS NULL
		   OR (c.Reported IS NULL AND @SWDate > i.Reported)
	OPEN cp
	FETCH NEXT FROM cp INTO @cPN, @cV, @cPV, @cRep, @cAct, @iPN, @iV, @iPV, @iRep
	WHILE @@FETCH_STATUS = 0
	BEGIN
		IF (@InvType = 'Full' AND (@cPN IS NULL OR @cV IS NULL))
			OR (@cAct = 'remove' AND @cV = @iV 
				AND NOT EXISTS(
					SELECT	*
					FROM	#CachePackage c
					WHERE	c.PackageName = @cPN
						AND c.Action = 'Add'
				)
			)
		BEGIN
			-- When processing full inventory, we want to 
			-- remove the Installation record if 
			-- CachePackage doesn't contain the record as
			-- it indicates that it's no longer installed.
			
			-- When processing differential inventory, we
			-- only want to remove the record with the 
			-- same version only if it's been removed and
			-- the same package is not being added as it 
			-- could indicate an upgrade or downgrade.

			IF @cRep IS NULL
				SELECT @cRep = getdate()

			-- Drop a message into InstallationHistory:
			IF NOT EXISTS( SELECT * FROM InstallationHistory
					WHERE ComputerID = @ComputerID
					AND UserID = @UserID
					AND PackageVersionID = @iPV
					AND Reported = @cRep
			)
			BEGIN
				INSERT InstallationHistory
					(ComputerId, PackageVersionID, UserID,
					 Action, Reported, Received, FailReasonID, Result)
					VALUES (@ComputerID, @iPV,
						@UserID, 'inv delete',
						@cRep, getdate(), NULL, 'success')
			END

			-- Delete the extraneous record(s):
			DELETE FROM Installation
			WHERE ComputerID = @ComputerID
			  AND UserID = @UserID
			  AND PackageVersionID IN (
				SELECT v.PackageVersionID
				FROM PackageVersion AS v, PackageFamily AS f
				WHERE f.PackageName= @iPN
				  AND v.PackageFamilyID = f.PackageFamilyID
				  AND v.Version = @iV
			)

			-- Count changes
			SELECT @Changes = @Changes + 1
		END ELSE IF (@iPN IS NULL OR @iV IS NULL)
				AND (@InvType = 'Full' OR @cAct = 'Add')
				AND NOT EXISTS(
					SELECT * FROM InstallationHistory
					WHERE ComputerID = @ComputerID
					  AND UserID = @UserID
					  AND PackageVersionID = @cPV
					  AND Action = 'uninstall'
					  AND Reported > @cRep
				)

		BEGIN
			-- When processing full inventory, we want to 
			-- add the record if the record doesn't exist 
			-- in the Installation table.
			
			-- When processing differential inventory, we
			-- only want to add the record only if it's being 
			-- added and the record doesn't exist in the 
			-- Installation table.

			-- Drop a message into InstallationHistory:
			IF NOT EXISTS( SELECT * FROM InstallationHistory
					WHERE ComputerID = @ComputerID
					AND UserID = @UserID
					AND PackageVersionID = @cPV
					AND Reported = @cRep
			)
			BEGIN
				INSERT InstallationHistory
					(ComputerId, PackageVersionID, UserID,
					 Action, Reported, Received, FailReasonID, Result)
					VALUES (@ComputerId, @cPV,
						@UserID, 'inv insert',
						@cRep, getdate(), NULL, 'success')
			END

			-- At present, update, upgrade, downgrade etc are all installs
			-- or installexs depending on the setting of Exclusive on the
			-- AllocationDetails
			IF EXISTS(
				SELECT	ad.*
				FROM	PackageApplies pa,
					Member m,
					AllocationDetails ad,
					PackagePath pp
				WHERE	pp.PackageFullName = @cFullname
				  AND	pp.PackagePathID = pa.PackagePathID
				  AND	((
						pa.TargetTypeID = CASE
							WHEN @UserID = 1 THEN 1 ELSE 2
							END
					 	AND	pa.TargetID = CASE
							WHEN @UserID = 1
								THEN @ComputerID
								ELSE @UserID
							END
					) OR (
						pa.TargetTypeID = 3 -- RSOP Group
						AND	m.GroupID = pa.TargetID
						AND	m.TargetTypeID = CASE
							WHEN @UserID = 1 THEN 1 ELSE 2
						END
						AND	m.TargetID = CASE
							WHEN @UserID = 1
							THEN @ComputerID
							ELSE @UserID
						END
					))
				  AND	pa.AllocationDetailsID = ad.AllocationDetailsID
				  AND	ad.Exclusive = 1
			)
			BEGIN
				SELECT @Action = 'installex'
			END ELSE BEGIN
				SELECT @Action = 'install'
			END

			-- Insert the new record:
			INSERT INTO Installation
				(ComputerId, PackageVersionID, UserID,
				 OrganizationID, Action, Reported, Received,
				 FailReasonID, Result)
				VALUES (
					@ComputerID, @cPV, @UserID, @OUID,
					@Action, @cRep, getdate(), NULL,
					'success'
				)

			-- Count changes
			SELECT @Changes = @Changes + 1
		END ELSE BEGIN
			IF @cV <> @iV AND (@InvType = 'Full' OR @cAct = 'Add')
			BEGIN
				-- If the version doesn't match, the installation has
				-- been modified (upgrade/downgrade). Thus we have to 
				-- update Installation record.

				-- Now update the version number
				UPDATE Installation
				SET PackageVersionID = @cPV, Reported = @cRep
					WHERE ComputerID = @ComputerID
					  AND UserID = @UserID
					  AND PackageVersionID = @iPV

				-- Drop a message into InstallationHistory:
				IF NOT EXISTS( SELECT * FROM InstallationHistory
						WHERE ComputerID = @ComputerID
						AND UserID = @UserID
						AND PackageVersionID = @cPV
						AND Reported = @cRep
				)
				BEGIN
					INSERT InstallationHistory
						(ComputerId, PackageVersionID,
						 UserID, Action, Reported, Received,
						 FailReasonID, Result)
						VALUES (@ComputerId, @cPV,
							@UserID, 'inv update',
							@cRep, getdate(),
							NULL, 'success')
				END
				-- Count changes
				SELECT @Changes = @Changes + 1
			END
		END
		FETCH NEXT FROM cp INTO @cPN, @cV, @cPV, @cRep, @cAct,
					@iPN, @iV, @iPV, @iRep
	END
	CLOSE cp
	DEALLOCATE cp

	-- Clean the table, it might be used again in this session:
	DELETE FROM #CachePackage
GO
-- $Id: PolicyUpdateBatch.sql 98927 2011-01-11 23:01:51Z tma $

IF EXISTS(SELECT * FROM sysobjects WHERE xtype = 'P'
		AND name = 'PolicyClearDuplicates')
	DROP PROCEDURE PolicyClearDuplicates
GO
CREATE PROCEDURE PolicyClearDuplicates
AS
	DELETE	ttp
	FROM	#PackageApplies AS ttp
	WHERE	EXISTS(	-- Same package exists a second time for this target
			-- or a schedule with lower precedence
			SELECT *
			FROM	#PackageApplies AS definitive
			WHERE	definitive.TargetOUID = ttp.TargetOUID
			  AND	definitive.TargetTypeID = ttp.TargetTypeID
			  AND	definitive.TargetID = ttp.TargetID
			  AND	(
					definitive.PackagePathID = ttp.PackagePathID OR
					(
						definitive.PackagePathID IN (
							SELECT	PackagePathID
							FROM	PackagePath
							WHERE	PackageFullName LIKE 'Schedule%'
						)
						AND ttp.PackagePathID IN (
							SELECT	PackagePathID
							FROM	PackagePath
							WHERE	PackageFullName LIKE 'Schedule%'
						)
					)
				)
			  AND	definitive.Precedence > ttp.Precedence
		)
GO

IF EXISTS(SELECT * FROM sysobjects WHERE xtype = 'P'
		AND name = 'PolicyInstallationUpdate')
	DROP PROCEDURE PolicyInstallationUpdate
GO
-- When a policy change withdraws a package, we update the Installation table:
-- * If the package is still installed, we mark it AS "redundant" or "residual"
-- * An installation record for a postponed installation must be deleted
-- When a policy is re-applied, a redundant or residual installation is restored
CREATE PROCEDURE PolicyInstallationUpdate
	@DomainID int = NULL,			-- Do all Domains
	@ParentOUReverse nvarchar(400) = NULL	-- Unused, historical
AS
	SELECT	pa.TargetTypeID,	-- PackageApplies to principal
		pa.TargetOUID,
		pa.TargetID,
		pa.PackagePathID,
		pa.AllocationDetailsID
	INTO	#p
	FROM	PackageApplies AS pa,
		Organization as o
	WHERE	pa.TargetOUID = o.OrganizationID
	  AND	(@DomainID IS NULL OR o.DomainID = @DomainID)
	  AND	pa.TargetTypeID <= 2	-- Users and Computers only

	INSERT	#p
	SELECT	t.TargetTypeID,		-- PackageApplies to RSoP group
		t.TargetOUID,
		t.TargetID,
		pa.PackagePathID,
		pa.AllocationDetailsID
	FROM	PackageApplies AS pa,
		[Group] as g,
		Organization AS o,
		Member AS tm,
		(
		SELECT	1 as TargetTypeID,
			c.ComputerOUID as TargetOUID,
			c.ComputerID as TargetID
		FROM	Computer as c,
			Organization as o
		WHERE	c.ComputerOUID = o.OrganizationID
		  AND	(@DomainID IS NULL OR o.DomainID = @DomainID)
		UNION ALL
		SELECT	2 as TargetTypeID,
			u.UserOUID as TargetOUID,
			u.UserID as TargetID
		FROM	[User] as u,
			Organization as o
		WHERE	u.UserOUID = o.OrganizationID
		  AND	(@DomainID IS NULL OR o.DomainID = @DomainID)
		) AS t					-- Users and Computers
	WHERE	pa.TargetTypeID = 3			-- RSoP Package Applies
	  AND	pa.TargetID = g.GroupID			-- to a group
	  AND	pa.TargetOUID = o.OrganizationID
	  AND	(@DomainID IS NULL OR o.DomainID = @DomainID)
	  AND	g.GroupID = tm.GroupID			-- Having a member
	  AND	tm.TargetTypeID = t.TargetTypeID	-- which is of this type
	  AND	tm.TargetID = t.TargetID		-- and this ID	


	DECLARE @count AS int
	SET @count = 0


	-- Update computer install records
	; WITH i2 AS (
		SELECT	i.ComputerID, i.UserID, i.PackageVersionID
			, Action = CASE WHEN ad.Exclusive IS NULL THEN 'install'
				    WHEN ad.Exclusive = 1 THEN 'installex'
				    ELSE 'installne'
				END
		FROM	Installation AS i		-- All Installations in the domain
			JOIN	Organization as o
				ON i.OrganizationID = o.OrganizationID
				AND (@DomainID IS NULL OR o.DomainID = @DomainID)
			JOIN	PackageVersion as pv
				ON i.PackageVersionID = pv.PackageVersionID
			LEFT OUTER JOIN #p			-- Compared with PackageApplies
				ON pv.PackagePathID = #p.PackagePathID
				  AND   i.OrganizationID = #p.TargetOUID
				  AND	i.ComputerID = #p.TargetID
				  AND	#p.TargetTypeID = 1
			LEFT OUTER JOIN AllocationDetails as ad
				ON #p.AllocationDetailsID = ad.AllocationDetailsID
		WHERE	i.UserID = 1
	)
	UPDATE	i
	SET	i.Action = i2.Action
	FROM    i2
	JOIN	Installation AS i ON i.ComputerID = i2.ComputerID AND i.UserID = i2.UserID AND i.PackageVersionID = i2.PackageVersionID AND i.Action != i2.Action

	SET @count = @count + @@ROWCOUNT


	-- Update user install records
	; WITH i2 AS (
		SELECT	i.ComputerID, i.UserID, i.PackageVersionID
			, Action = CASE WHEN ad.Exclusive IS NULL THEN 'install'
				    WHEN ad.Exclusive = 1 THEN 'installex'
				    ELSE 'installne'
				END
		FROM	Installation AS i		-- All Installations in the domain
			JOIN	Organization as o
				ON i.OrganizationID = o.OrganizationID
				AND (@DomainID IS NULL OR o.DomainID = @DomainID)
			JOIN	PackageVersion as pv
				ON i.PackageVersionID = pv.PackageVersionID
			LEFT OUTER JOIN #p			-- Compared with PackageApplies
				ON pv.PackagePathID = #p.PackagePathID
				  AND   i.OrganizationID = #p.TargetOUID
				  AND	i.UserID = #p.TargetID
				  AND	#p.TargetTypeID = 2
			LEFT OUTER JOIN AllocationDetails as ad
				ON #p.AllocationDetailsID = ad.AllocationDetailsID
		WHERE	i.UserID != 1
	)
	UPDATE	i
	SET	i.Action = i2.Action
	FROM    i2
	JOIN	Installation AS i ON i.ComputerID = i2.ComputerID AND i.UserID = i2.UserID AND i.PackageVersionID = i2.PackageVersionID AND i.Action != i2.Action

	SET @count = @count + @@ROWCOUNT


	RETURN @count
GO

IF EXISTS(SELECT * FROM sysobjects WHERE xtype = 'P'
		AND name = 'PolicyAppliesReplaceSubsetByParentOrganization')
	DROP PROCEDURE PolicyAppliesReplaceSubsetByParentOrganization
GO
CREATE PROCEDURE PolicyAppliesReplaceSubsetByParentOrganization
	@DomainID		int,
	@ParentOUReverse	nvarchar(400),
	@ExcludeWithMemberTargetTypeID	int = 0
AS
	DECLARE @count AS int
	SET @count = 0

	-- Delete non-group members (excluding the specified type)
	DELETE PolicyApplies
		FROM	Organization AS o
		WHERE	@DomainID = PolicyApplies.DomainID -- Right domain
		  AND	@DomainID = o.DomainID
		  AND	PolicyApplies.TargetOUID = o.OrganizationID
		  AND	TargetTypeID <> @ExcludeWithMemberTargetTypeID
		  AND	TargetTypeID <> 3
		  AND	(o.RDNReverse+',') LIKE (
			    CASE @ParentOUReverse
				WHEN '' THEN '%'
				ELSE @ParentOUReverse+',%'
			    END
			) --Sub-OU
		  AND NOT EXISTS(	-- Replacement record doesn't exist
			SELECT * FROM #PolicyApplies AS t
				WITH(INDEX(TempPolicyAppliesByTargetOUIDTargetTypeIDTargetID))
			WHERE	@DomainID = t.DomainID
			  AND	PolicyApplies.TargetOUID = t.TargetOUID
			  AND	PolicyApplies.TargetTypeID = t.TargetTypeID
			  AND	PolicyApplies.TargetID = t.TargetID
			  AND	PolicyApplies.GUID = t.GUID
		  )

	-- Delete groups (excluding those that contain members of the specified type)
	DELETE PolicyApplies
		FROM	Organization AS o
		WHERE	@DomainID = PolicyApplies.DomainID -- Right domain
		  AND	@DomainID = o.DomainID
		  AND	PolicyApplies.TargetOUID = o.OrganizationID
		  AND	TargetTypeID = 3
		  AND	(o.RDNReverse+',') LIKE (
			    CASE @ParentOUReverse
				WHEN '' THEN '%'
				ELSE @ParentOUReverse+',%'
			    END
			) --Sub-OU
		  AND NOT EXISTS(	-- Replacement record doesn't exist
			SELECT * FROM #PolicyApplies AS t
				WITH(INDEX(TempPolicyAppliesByTargetOUIDTargetTypeIDTargetID))
			WHERE	@DomainID = t.DomainID
			  AND	PolicyApplies.TargetOUID = t.TargetOUID
			  AND	PolicyApplies.TargetTypeID = t.TargetTypeID
			  AND	PolicyApplies.TargetID = t.TargetID
			  AND	PolicyApplies.GUID = t.GUID
		  )
		  AND NOT EXISTS (
			SELECT *
			FROM Member
			WHERE PolicyApplies.TargetID = Member.GroupID
			AND Member.TargetTypeID = @ExcludeWithMemberTargetTypeID 
		  )

	INSERT PolicyApplies (
		DomainID,
		TargetOUID,
		TargetTypeID,
		TargetID,
		GUID
	)
		SELECT	DomainID,
			TargetOUID,
			TargetTypeID,
			TargetID,
			GUID
		FROM	#PolicyApplies AS t
		WHERE NOT EXISTS(	-- Current record doesn't exist
			SELECT * FROM PolicyApplies
			WHERE	PolicyApplies.DomainID = t.DomainID
			  AND	PolicyApplies.TargetOUID = t.TargetOUID
			  AND	PolicyApplies.TargetTypeID = t.TargetTypeID
			  AND	PolicyApplies.TargetID = t.TargetID
			  AND	PolicyApplies.GUID = t.GUID
		)
	SET @count = @count + @@ROWCOUNT
	DROP TABLE #PolicyApplies	-- Remove the temporary table
	RETURN @count
GO

IF EXISTS(SELECT * FROM sysobjects WHERE xtype = 'P'
		AND name = 'PolicyRemoveOld')
	DROP PROCEDURE PolicyRemoveOld
GO
CREATE PROCEDURE PolicyRemoveOld
	@DomainID int,
	@ParentOUReverse nvarchar(400),
	@ExcludeWithMemberTargetTypeID	int = 0
AS
	DECLARE @count AS integer

	-- Delete non-group members (excluding the specified type)
	DELETE	PackageApplies
		FROM Organization AS o
		WHERE PackageApplies.TargetOUID = o.OrganizationID
		  AND o.DomainID = @DomainID	-- Right domain
		  AND TargetTypeID <> @ExcludeWithMemberTargetTypeID
		  AND TargetTypeID <> 3
		  AND	(o.RDNReverse+',') LIKE (
			    CASE @ParentOUReverse
				WHEN '' THEN '%'
				ELSE @ParentOUReverse+',%'
			    END
			) --Sub-OU
		  AND NOT EXISTS(
			SELECT ttp.TargetID
			FROM #PackageApplies AS ttp WITH(INDEX(TempPackageApplies))
			WHERE PackageApplies.TargetOUID = ttp.TargetOUID
			  AND PackageApplies.TargetTypeID = ttp.TargetTypeID
			  AND PackageApplies.TargetID = ttp.TargetID
			  AND PackageApplies.PackagePathID = ttp.PackagePathID
			  AND PackageApplies.PolicyGUID = ttp.PolicyGUID
		)
	-- Delete groups (excluding those that contain members of the specified type)
	DELETE	PackageApplies
		FROM Organization AS o
		WHERE PackageApplies.TargetOUID = o.OrganizationID
		  AND o.DomainID = @DomainID	-- Right domain
		  AND TargetTypeID = 3
		  AND	(o.RDNReverse+',') LIKE (
			    CASE @ParentOUReverse
				WHEN '' THEN '%'
				ELSE @ParentOUReverse+',%'
			    END
			) --Sub-OU
		  AND NOT EXISTS(
			SELECT ttp.TargetID
			FROM #PackageApplies AS ttp WITH(INDEX(TempPackageApplies))
			WHERE PackageApplies.TargetOUID = ttp.TargetOUID
			  AND PackageApplies.TargetTypeID = ttp.TargetTypeID
			  AND PackageApplies.TargetID = ttp.TargetID
			  AND PackageApplies.PackagePathID = ttp.PackagePathID
			  AND PackageApplies.PolicyGUID = ttp.PolicyGUID
		)
		AND NOT EXISTS (
			SELECT *
			FROM Member
			WHERE PackageApplies.TargetID = Member.GroupID
			AND Member.TargetTypeID = @ExcludeWithMemberTargetTypeID 
		)

	SET @count = @@ROWCOUNT
GO

IF EXISTS(SELECT * FROM sysobjects WHERE xtype = 'P'
		AND name = 'PackageAppliesReplaceSubsetByParentOrganisation')
	DROP PROCEDURE PackageAppliesReplaceSubsetByParentOrganisation
GO
CREATE PROCEDURE PackageAppliesReplaceSubsetByParentOrganisation
	@DomainID		int,
	@ParentOUReverse	nvarchar(400),
	@ExcludeWithMemberTargetTypeID	int = 0
AS
	DECLARE @count AS int
	SET @count = 0

	EXEC PolicyRemoveOld @DomainID, @ParentOUReverse, @ExcludeWithMemberTargetTypeID

	UPDATE o
		SET	AllocationDetailsID = t.AllocationDetailsID,
			Precedence = t.Precedence,
			PolicyVersion = t.PolicyVersion
		FROM	#PackageApplies AS t,
			PackageApplies AS o
		WHERE	o.TargetOUID = t.TargetOUID
		  AND	o.TargetTypeID = t.TargetTypeID
		  AND	o.TargetID = t.TargetID
		  AND	o.PackagePathID = t.PackagePathID
		  AND	o.PolicyGUID = t.PolicyGUID
	SET @count = @@ROWCOUNT

	INSERT PackageApplies (
		TargetTypeID,
		TargetOUID,
		TargetID,
		PackagePathID,
		PolicyGUID,
		AllocationDetailsID,
		Precedence,
		PolicyVersion
	)
		SELECT	TargetTypeID,
			TargetOUID,
			TargetID,
			PackagePathID,
			PolicyGUID,
			AllocationDetailsID,
			Precedence,
			PolicyVersion
		FROM	#PackageApplies AS t
		WHERE NOT EXISTS(	-- Current record doesn't exist
			SELECT * FROM PackageApplies
			WHERE	PackageApplies.TargetOUID = t.TargetOUID
			  AND	PackageApplies.TargetTypeID = t.TargetTypeID
			  AND	PackageApplies.TargetID = t.TargetID
			  AND	PackageApplies.PackagePathID = t.PackagePathID
			  AND	PackageApplies.PolicyGUID = t.PolicyGUID
		)
GO

/*
 * This procedure integrates the results of a policy merge into the database
 * from two temporary tables, #PolicyApplies and #PackageApplies.
 * These tables have the same shape as the permanents versions, but will
 * only contains results for the DomainID specified, and is ParentOU is
 * set, for Users&Computers in and under that OU (a domain-relative RDN).
 *
 * The ParentOU is reversed to become @ParentOUReverse, and the following
 * somewhat arcane filter clauses are used in several places:
 *
 *	  AND	(o.RDNReverse+',') LIKE (
 *		    CASE @ParentOUReverse
 *			WHEN '' THEN '%'
 *			ELSE @ParentOUReverse+',%'
 *		    END
 *		) --Sub-OU
 *
 * The first clause allows the SQL Query optimiser to use the Organization
 * tables RDNReverse index. The second clause ParentOUReverse eliminates
 * false matches: In case you have two OUs called say "OU=foo" and "OU=foobar"
 * and want to match on "OU=foo", the 2nd clause eliminates "OU=foobar".
 *
 * Most other formulations of these clauses do not allow the use of the
 * RDNReverse index, so beware!
 */
IF EXISTS(SELECT * FROM sysobjects WHERE xtype = 'P'
		AND name = 'PolicyUpdateBatch')
	DROP PROCEDURE PolicyUpdateBatch
GO
CREATE PROCEDURE PolicyUpdateBatch
	@DomainID		int,
	@ParentOU nvarchar(400) = NULL,
	@ExcludeWithMemberTargetTypeID int = 0
AS
	DECLARE @ParentOUReverse nvarchar(400)

	-- Reverse the DN
	IF (@ParentOU IS NULL OR @ParentOU = '')
		SET @ParentOUReverse = ''
	ELSE
		EXEC ReverseDN @ParentOU, @ParentOUReverse OUTPUT

	CREATE NONCLUSTERED INDEX TempPackageApplies
		ON #PackageApplies(TargetOUID, TargetTypeID, TargetID, PackagePathID, PolicyGUID)

	CREATE INDEX [TempPolicyAppliesByTargetOUIDTargetTypeIDTargetID]
		ON #PolicyApplies (TargetOUID, TargetTypeID, TargetID, GUID)

	EXEC PolicyClearDuplicates	-- Delete unnecessary entries from new

	-- Merge new PolicyApplies
	EXEC PolicyAppliesReplaceSubsetByParentOrganization @DomainID, @ParentOUReverse, @ExcludeWithMemberTargetTypeID

	EXEC PackageAppliesReplaceSubsetByParentOrganisation @DomainID, @ParentOUReverse, @ExcludeWithMemberTargetTypeID

	DROP TABLE #PackageApplies	-- Clean the temporary table

	-- Fix incorrect AllocationDetailsID for Installation Postponement
	-- Targeted directly
	UPDATE	ip
	SET	ip.AllocationDetailsID = pa.AllocationDetailsID
	FROM	dbo.InstallationPostponement as ip,
		dbo.PackageApplies as pa,
		dbo.Organization as o
	WHERE	pa.TargetOUID = o.OrganizationID
	  AND	o.DomainID = @DomainID
	  AND	ip.TargetTypeID = pa.TargetTypeID
	  AND	ip.TargetID = pa.TargetID
	  AND	ip.PackagePathID = pa.PackagePathID
	  AND	ip.PolicyGUID = pa.PolicyGUID
	  AND	ip.AllocationDetailsID <> pa.AllocationDetailsID

	-- Fix incorrect AllocationDetailsID for Installation Postponement
	-- Targeted indirectly via group
	UPDATE	ip
	SET	ip.AllocationDetailsID = pa.AllocationDetailsID
	FROM	dbo.InstallationPostponement as ip,
		dbo.PackageApplies as pa,
		dbo.Member as m,
		dbo.Organization as o
	WHERE	pa.TargetOUID = o.OrganizationID
	  AND	o.DomainID = @DomainID
	  AND	pa.TargetTypeID = 3 -- RSOP Groups
	  AND	pa.TargetID = m.GroupID
	  AND	ip.TargetTypeID = m.TargetTypeID
	  AND	ip.TargetID = m.TargetID
	  AND	ip.PackagePathID = pa.PackagePathID
	  AND	ip.PolicyGUID = pa.PolicyGUID
	  AND	ip.AllocationDetailsID <> pa.AllocationDetailsID

	-- Fix Installations; not here, too slow and only handles corner cases anyhow
	-- EXEC PolicyInstallationUpdate @DomainID, @ParentOUReverse

	-- Update last-merge time if it's a full-domain merge.
	IF (@ParentOU IS NULL OR @ParentOU = '')
		UPDATE DomainConfiguration
		SET	Value = getdate(),
			DateValue = getdate(),
			LastUpdate = getdate()
		WHERE DomainID = @DomainID and Property = 'LastPolicyMerge'
GO
PRINT 'Creating procedure to update policy merge status'
IF EXISTS(SELECT * FROM sysobjects WHERE xtype = 'P'
		AND name = 'DomainUpdatePolicyMergeStatus')
	DROP PROCEDURE DomainUpdatePolicyMergeStatus
GO
CREATE PROCEDURE DomainUpdatePolicyMergeStatus
	@DomainID int,
	@Success bit
AS
	UPDATE Domain
	SET LastPolicyMergeStatus = @Success
	WHERE OrganizationID = @DomainID
GO
-- $Id: PolicySubsets.sql 84480 2007-07-24 06:34:27Z pca $

-- This procedure is used by the ManageSoft Version 6 polmerge:
IF EXISTS(SELECT * FROM sysobjects WHERE xtype = 'P'
		AND name = 'PolicyAppliesReplaceSubsetByPolicyDomainID')
	DROP PROCEDURE PolicyAppliesReplaceSubsetByPolicyDomainID
GO
-- Replace the record subset selected by (Policy.@DomainID), populating missing policies.
CREATE PROCEDURE PolicyAppliesReplaceSubsetByPolicyDomainID
	@DomainID		int
AS
	-- Any policies not populated by PackageApplies update
	-- must be created now (no DisplayName)
	INSERT Policy(GUID, DomainID)
		SELECT DISTINCT GUID, @DomainID
		FROM #PolicyApplies
		WHERE NOT EXISTS(
			SELECT * FROM Policy
			WHERE Policy.GUID = #PolicyApplies.GUID
		)
	EXEC PolicyAppliesReplaceSubsetByDomainID @DomainID
GO

IF EXISTS(SELECT * FROM sysobjects WHERE xtype = 'P'
		AND name = 'PackageAppliesReplaceSubsetByDomainID')
	DROP PROCEDURE PackageAppliesReplaceSubsetByDomainID
GO
CREATE PROCEDURE PackageAppliesReplaceSubsetByDomainID
	@DomainID		int
AS
	DECLARE @count AS int
	SET @count = 0
	BEGIN TRANSACTION
	DELETE tp
		FROM	PackageApplies AS tp,
			Organization as o
		WHERE	o.DomainID = @DomainID
		  AND	tp.TargetOUID = o.OrganizationID
		AND NOT EXISTS(		-- Replacement record doesn't exist
			SELECT	* FROM #PackageApplies AS t
			WHERE	tp.TargetOUID = t.TargetOUID
			  AND	tp.TargetTypeID = t.TargetTypeID
			  AND	tp.TargetID = t.TargetID
			  AND	tp.PackagePathID = t.PackagePathID
			  AND	tp.PolicyGUID = t.PolicyGUID
		)

	UPDATE o
		SET	AllocationDetailsID = t.AllocationDetailsID,
			Precedence = t.Precedence,
			PolicyVersion = t.PolicyVersion
		FROM	#PackageApplies AS t,
			PackageApplies AS o
		WHERE	o.TargetOUID = t.TargetOUID
		  AND	o.TargetTypeID = t.TargetTypeID
		  AND	o.TargetID = t.TargetID
		  AND	o.PackagePathID = t.PackagePathID
		  AND	o.PolicyGUID = t.PolicyGUID
	SET @count = @@ROWCOUNT

	INSERT PackageApplies (
		TargetTypeID,
		TargetOUID,
		TargetID,
		PackagePathID,
		PolicyGUID,
		AllocationDetailsID,
		Precedence,
		PolicyVersion
	)
		SELECT	TargetTypeID,
			TargetOUID,
			TargetID,
			PackagePathID,
			PolicyGUID,
			AllocationDetailsID,
			Precedence,
			PolicyVersion
		FROM	#PackageApplies AS t
		WHERE NOT EXISTS(	-- Current record doesn't exist
			SELECT * FROM PackageApplies
			WHERE	PackageApplies.TargetOUID = t.TargetOUID
			  AND	PackageApplies.TargetTypeID = t.TargetTypeID
			  AND	PackageApplies.TargetID = t.TargetID
			  AND	PackageApplies.PackagePathID = t.PackagePathID
			  AND	PackageApplies.PolicyGUID = t.PolicyGUID
		)
	SET @count = @count + @@ROWCOUNT
	DELETE FROM #PackageApplies	-- Clean the temporary table
	COMMIT WORK
	RETURN @count
GO

IF EXISTS(SELECT * FROM sysobjects WHERE xtype = 'P'
		AND name = 'PackageAllocationReplaceSubsetByDomain')
	DROP PROCEDURE PackageAllocationReplaceSubsetByDomain
GO
-- Replace the record subset selected by (@DomainID)
-- using unique identifier (PolicyGUID, TargetTypeID, PackagePathID, AllocationDetailsID)
-- updating fields (AccessGroupID, Precedence)
CREATE PROCEDURE PackageAllocationReplaceSubsetByDomain
	@DomainID		int
AS
	DECLARE @count AS int
	SET @count = 0

	CREATE INDEX [TempPackageAllocationByDomain]
		ON #PackageAllocation (PolicyGUID, TargetTypeID, PackagePathID, AllocationDetailsID)

	BEGIN TRANSACTION
	DELETE pa
		FROM	PackageAllocation as pa,
			Policy as p
		WHERE	@DomainID = p.DomainID
		  AND	p.GUID = pa.PolicyGUID
		AND NOT EXISTS(		-- Replacement record doesn't exist
			SELECT * FROM #PackageAllocation AS t
			WHERE	pa.PolicyGUID = t.PolicyGUID
			  AND	pa.TargetTypeID = t.TargetTypeID
			  AND	pa.PackagePathID = t.PackagePathID
			  AND	pa.AllocationDetailsID = t.AllocationDetailsID
		)

	UPDATE	PackageAllocation
		SET	AccessGroupID = t.AccessGroupID,
			Precedence = t.Precedence
		FROM	#PackageAllocation AS t
		WHERE	PackageAllocation.PolicyGUID = t.PolicyGUID
		  AND	PackageAllocation.TargetTypeID = t.TargetTypeID
		  AND	PackageAllocation.PackagePathID = t.PackagePathID
		  AND	PackageAllocation.AllocationDetailsID = t.AllocationDetailsID
	SET @count = @@ROWCOUNT

	INSERT PackageAllocation (
		PolicyGUID,
		PackagePathID,
		AccessGroupID,
		TargetTypeID,
		Precedence,
		AllocationDetailsID
	)
		SELECT	PolicyGUID,
			PackagePathID,
			AccessGroupID,
			TargetTypeID,
			Precedence,
			AllocationDetailsID
		FROM	#PackageAllocation AS t
		WHERE NOT EXISTS(	-- Current record doesn't exist
			SELECT * FROM PackageAllocation
			WHERE	PackageAllocation.PolicyGUID = t.PolicyGUID
			  AND	PackageAllocation.TargetTypeID = t.TargetTypeID
			  AND	PackageAllocation.PackagePathID = t.PackagePathID
			  AND	PackageAllocation.AllocationDetailsID = t.AllocationDetailsID
		)
		AND NOT EXISTS(		-- Another having the same details
			SELECT * FROM #PackageAllocation as pa2
			WHERE	pa2.PolicyGUID = t.PolicyGUID
			  AND	pa2.TargetTypeID = t.TargetTypeID
			  AND	pa2.PackagePathID = t.PackagePathID
			  AND	pa2.AllocationDetailsID = t.AllocationDetailsID
			  AND	pa2.AccessGroupID < t.AccessGroupID
		)
	SET @count = @count + @@ROWCOUNT
	DROP TABLE #PackageAllocation	-- Drop the temporary table
	COMMIT WORK
	RETURN @count
GO
/*
 * $Id: ReconcileComputers.sql 95296 2009-12-11 02:25:16Z rlowery $
 *
 * Reconcile the database with changes in one Active Directory Domain
 *
 * Protected by US patent 6,006,034; patents pending.
 * Copyright 2000-2002 ManageSoft Corporation. All rights reserved.
 * Reproduction, adaptation, or translation without prior permission
 * is prohibited.
 */
-- USE ManageSoft
GO

PRINT 'Creating procedure to reconcile Computers in an AD Domain'
IF EXISTS(SELECT * FROM sysobjects WHERE xtype = 'P'
	AND name = 'ReconcileComputers'
)
	DROP PROCEDURE ReconcileComputers
GO
CREATE PROCEDURE ReconcileComputers
	@DomainID	int,
	@Populate	BIT = 0,	-- Add all missing computers
	@ParentOU	nvarchar(400) = NULL	-- not all computers are in ADComputer
AS
	DECLARE @count AS int
	DECLARE @loops AS int

	-- AD field values
	DECLARE @aGUID AS binary(16)	-- GUID from AD
	DECLARE @aCN AS nvarchar(64)	-- Common Name
	DECLARE @aOUID AS int		-- Organization ID of target OU
	DECLARE @aOU AS nvarchar(400)	-- OU RDN of target OU

	-- SQL field values
	DECLARE @sCN AS nvarchar(64)	-- Common Name
	DECLARE @sOUID AS int		-- Organization ID
	DECLARE @sID AS INT		-- Computer SQL ID
	DECLARE @bID AS INT		-- Blocking ComputerID
	DECLARE @bCN AS nvarchar(64)	-- Blocking Computer CN
	DECLARE @bWontFix AS INT	-- Blocking Computer won't get fixed?

	DECLARE @newOUID AS INT		-- ID of new SD for moved computer
	DECLARE @unknownOUID AS INT	-- ID of unknown OU in domain

	SELECT	@unknownOUID = OrganizationID
	FROM	Organization
	WHERE	DomainID = @DomainID
	  AND	RDN IS NULL

	-- Make sure that all matching DNs have their GUIDs set appropriately:
	EXEC PopulateComputerGUIDs

	DECLARE @msg varchar(1024)
	SELECT @msg = 'Reconciling Computers in '+DN
		FROM Domain where OrganizationID = @DomainID
	PRINT @msg

	-- Delete Computers whose GUIDs no longer exist:
	SELECT	c.ComputerID
	INTO	#Computer
	FROM	Computer AS c,
		Organization AS o
	WHERE	c.GUID IS NOT NULL
	  AND	c.ComputerOUID = o.OrganizationID
	  AND	o.DomainID = @DomainID
	  AND NOT EXISTS(
		SELECT * FROM ADComputer AS a
		WHERE	@DomainID = a.DomainID
		  AND	c.GUID = a.GUID
		)
	  AND ISNULL(@ParentOU, '') = ''

	-- Delete Computers with duplicate GUIDs. This should never
        -- happen, but databases have been known to become corrupted
        -- for one reason or another, and so we try to fix it up here
        -- by arbitrarily choosing one of the duplicates to be
        -- deleted.
	INSERT	#Computer(ComputerID)
	SELECT	c2.ComputerID
	FROM	Computer AS c1
		INNER JOIN Computer c2 ON c1.GUID = c2.GUID
	WHERE	c1.GUID IS NOT NULL
		AND c1.ComputerID < c2.ComputerID


	EXEC DeleteComputers
	DROP TABLE #Computer
	
	-- Now move any computers in known OUs with NULL GUIDs to Unknown OU
	-- or in the case of a partial merge are no longer in the OU being merged
	SELECT	ComputerID, @unknownOUID AS NewOUID
	INTO	#ComputersToMove
	FROM	Computer AS c,
		Organization AS o
	WHERE (c.GUID IS NULL			-- With a NULL GUID
	  OR ( NOT ISNULL(@ParentOU, '') = ''
			AND RIGHT(o.RDN, LEN(@ParentOU)) = @ParentOU
			AND NOT EXISTS	-- GUID isn't already attached
				(SELECT * FROM ADComputer AS adc WHERE c.GUID = adc.GUID)
		)
	  )
	  AND c.ComputerOUID = o.OrganizationID	-- Match organization
	  AND o.DomainID = @DomainID		-- In this domain
	  AND o.RDN IS NOT NULL			-- Not the unknown OU

	EXEC MoveComputersToNewOU
	TRUNCATE TABLE #ComputersToMove

	-- Rename/Move computers. We loop, because if A->B and B->C, we must
	-- handle A specially. We could skip renaming A until B is done, but
	-- that would loop infinitely if A->B and B->A. So instead whenever
	-- a rename is blocked by a computer of the same name, we rename
	-- first to a temporary name. This guarantees that the loop will
	-- complete on the second pass. A slight optimization that's omitted
	-- because of complexity would be to only do a temporary rename when
	-- the current computer is both blocked and blocking another - the
	-- case is very infrequent and the cost low.
	SET @count = 1
	SET @loops = 0
	WHILE @count > 0 AND @loops < 10
	BEGIN
		SET @count = 0
		SET @loops = @loops + 1
		DECLARE computers CURSOR FOR
			SELECT	c.ComputerID,		-- This computer
				c.ComputerOUID AS ActualOU, -- is here
				c.ComputerCN AS ActualCN,   -- called this, but
				a.ComputerOUID AS TargetOU, -- should be here
				CASE WHEN blocker.ComputerID IS NOT NULL
					THEN	NULL
					ELSE	a.ComputerCN
				END AS TargetCN,	-- called this
				blocker.ComputerID AS BlockerID,
				blocker.ComputerCN AS BlockerCN,
				CASE	WHEN blocker.ComputerID IS NOT NULL
						AND ablocker.GUID IS NULL
					THEN 1
					ELSE 0
				END AS BlockerWontGetFixed
			FROM (		-- The Computers we actually have
				SELECT	c.*
				FROM	Computer AS c,
					Organization AS o
				WHERE	@DomainID = o.DomainID
				  AND	o.OrganizationID = c.ComputerOUID
			     ) AS c
			     INNER JOIN
			     (		-- The Computers we want
				SELECT	target_o.OrganizationID AS ComputerOUID,
					a.ComputerCN,
					a.GUID
				FROM	ADComputer AS a
					INNER JOIN Organization AS target_o
					    ON a.ComputerOURDN = target_o.RDN
				WHERE	@DomainID = a.DomainID
				  AND	@DomainID = target_o.DomainID
			     ) AS a
				ON c.GUID = a.GUID	-- Same computer
			     LEFT OUTER JOIN Computer blocker
				 ON	c.ComputerID <> blocker.ComputerID
				 AND	a.ComputerOUID = blocker.ComputerOUID
				 AND	a.ComputerCN = blocker.ComputerCN
			     LEFT OUTER JOIN ADComputer ablocker
				 ON	ablocker.GUID = blocker.GUID
			WHERE	c.ComputerOUID <> a.ComputerOUID -- Wrong place
				OR ISNULL(c.ComputerCN,'')	-- Wrong name
					<> ISNULL(a.ComputerCN,'')

		OPEN computers
		FETCH NEXT FROM computers INTO @sID, @sOUID, @sCN,
			@aOUID, @aCN, @bID, @bCN, @bWontFix
		WHILE @@FETCH_STATUS = 0
		BEGIN
			SET @count = @count+1

			IF @bWontFix = 1
			BEGIN
				-- We have a computer blocking our rename that
				-- is not going to be moved/renamed within this
				-- loop: we have to take some drastic action to
				-- get it out of the way!

				IF EXISTS (
					SELECT	*
					FROM	Computer c
					WHERE	c.ComputerCN = @bCN
						AND c.ComputerOUID=@unknownOUID
				)
				BEGIN
					-- We've already got a computer in the
					-- unknown OU with our blocker's name,
					-- so we can't just move the blocker
					-- in... We know that the blocker
					-- computer must have been renamed (or
					-- deleted), but we don't know the
					-- details. So for now, we just give it
					-- a "temporary name". Future AD
					-- reconciles will fix this up.

					DECLARE @newCN AS nvarchar(64)
					SET @newCN = 'renamed computer'+STR(RAND()*1000000000)
					EXEC RenameComputer @bID, @newCN
				END

				INSERT INTO #ComputersToMove(ComputerID, NewOUID)
				VALUES (@bID, @unknownOUID)
			END

			-- If Computer's in wrong OU, move it
			IF @sOUID <> @aOUID
			BEGIN
				INSERT INTO #ComputersToMove(ComputerID, NewOUID)
				VALUES (@sID, @aOUID)
			END

			-- If Computer exists, but has wrong CN, fix it
			IF @aCN IS NULL
				SET @aCN = 'temp'+STR(RAND()*1000000000)

			IF (@aCN <> ISNULL(@sCN,''))
				EXEC RenameComputer @sID, @aCN

			FETCH NEXT FROM computers INTO @sID, @sOUID, @sCN, @aOUID, @aCN, @bID, @bCN, @bWontFix
		END
		CLOSE computers
		DEALLOCATE computers

		EXEC MoveComputersToNewOU
		TRUNCATE TABLE #ComputersToMove
	END

	IF @loops >= 10
	BEGIN
		SELECT @msg = 'Reconciliation of Computers in '+DN+' failed to stabilize after 10 iterations'
			FROM Domain where OrganizationID = @DomainID
		PRINT @msg
	END

	-- Populate missing Computers if requested
	IF @Populate <> 0
	BEGIN
		EXEC DomainComputerPopulate @DomainID
	END

	-- Now go through the unknown OU to see if any computers can be
	-- moved to their correct places.
	DECLARE computer_cur CURSOR FOR
		SELECT ComputerID, ComputerCN
			FROM Computer
			WHERE ComputerOUID = @unknownOUID
			  AND GUID IS NULL

	OPEN computer_cur
	FETCH NEXT FROM computer_cur INTO @sID, @sCN
	WHILE @@FETCH_STATUS = 0
	BEGIN
		-- N.B. If not found, variables retain *previous* value!
		SELECT @aCN = ComputerCN, @aOU = ComputerOURDN, @aGUID = GUID
			FROM ADComputer
			WHERE ComputerCN = @sCN
			  AND DomainID = @DomainID

		IF (@@ROWCOUNT = 1)
		BEGIN
			SELECT @aOUID = OrganizationID
				FROM Organization
				WHERE RDN = @aOU
				  AND DomainID = @DomainID

			IF (@@ROWCOUNT = 1)
			BEGIN
				-- Check that Target doesn't already exist
				-- either by name or by GUID
				IF EXISTS(
					SELECT * FROM Computer
					WHERE ComputerID <> @sID
					  AND (GUID = @aGUID
						OR (ComputerOUID = @aOUID
							AND ComputerCN = @sCN
						)
					)
				) BEGIN
					-- Target location/GUID for computer is
					-- in use, delete unknown duplicate
					EXEC DeleteComputer @sID
				END ELSE BEGIN
					UPDATE Computer SET GUID = @aGUID
						WHERE ComputerID = @sID
					INSERT INTO #ComputersToMove(ComputerID, NewOUID)
					VALUES (@sID, @aOUID)
				END
			END
		END

		FETCH NEXT FROM computer_cur INTO @sID, @sCN
	END
	CLOSE computer_cur
	DEALLOCATE computer_cur
	
	EXEC MoveComputersToNewOU
	DROP TABLE #ComputersToMove
GO
/*
 * $Id: ReconcileOrganizations.sql 84480 2007-07-24 06:34:27Z pca $
 *
 * Reconcile the database with changes in one Active Directory Domain
 *
 * Protected by US patent 6,006,034; patents pending.
 * Copyright 2000-2002 ManageSoft Corporation. All rights reserved.
 * Reproduction, adaptation, or translation without prior permission
 * is prohibited.
 */
-- USE ManageSoft
GO

PRINT 'Creating procedure to reconcile Organizations in an AD Domain'
IF EXISTS(SELECT * FROM sysobjects WHERE xtype = 'P'
	AND name = 'ReconcileOrganizations'
)
	DROP PROCEDURE ReconcileOrganizations
GO
CREATE PROCEDURE ReconcileOrganizations
	@DomainID	int
AS
	DECLARE @count as int
	DECLARE @loops AS int

	-- AD field values
	DECLARE @aRDN as nvarchar(400)
	DECLARE @aGUID as binary(16)

	-- SQL field values
	DECLARE @sRDN as nvarchar(400)
	DECLARE @sGUID as binary(16)
	DECLARE @sID as INT

	-- Make sure that all matching DNs have their GUIDs set appropriately:
	-- This is required by the 2nd DeleteOrganization case below!
	EXEC PopulateOrganizationGUIDs

	DECLARE @msg varchar(1024)
	SELECT @msg = 'Reconciling Organizations in '+DN
		FROM Domain where OrganizationID = @DomainID
	PRINT @msg

	-- Delete OUs whose GUIDs no longer exist in AD, and
	-- those with NULL guids whose RDNs don't exist in AD
	DECLARE ou_cur CURSOR FOR
		SELECT	o.OrganizationID
		FROM	Organization AS o
		WHERE	@DomainID = o.DomainID
		  AND (	(o.GUID IS NOT NULL
			  AND NOT EXISTS(
				SELECT * FROM ADSDOU AS a
				WHERE	@DomainID = a.DomainID
				  AND	o.GUID = a.GUID
				)
			) OR
			(o.GUID IS NULL
			 AND o.RDN IS NOT NULL
			 AND NOT EXISTS(
				SELECT * FROM ADSDOU AS a
				WHERE	@DomainID = a.DomainID
				  AND	o.RDN = a.RDN
			 )
			)
		  )
	OPEN ou_cur
	FETCH NEXT FROM ou_cur INTO @sID
	WHILE @@FETCH_STATUS = 0
	BEGIN
		EXEC DeleteOrganization @sID
		FETCH NEXT FROM ou_cur INTO @sID
	END
	CLOSE ou_cur
	DEALLOCATE ou_cur

	-- Delete OUs with duplicate GUIDs. This should never
        -- happen, but databases have been known to become corrupted
        -- for one reason or another, and so we try to fix it up here
        -- by arbitrarily choosing one of the duplicates to be
        -- deleted.
	DECLARE ou_cur CURSOR FOR
		SELECT	DISTINCT o2.RDN, o2.OrganizationID
		FROM	Organization AS o1
			INNER JOIN Organization o2 ON o2.GUID = o1.GUID
		WHERE	o1.GUID IS NOT NULL
			AND o1.OrganizationID < o2.OrganizationID
	OPEN ou_cur
	FETCH NEXT FROM ou_cur INTO @sRDN, @sID
	WHILE @@FETCH_STATUS = 0
	BEGIN
		SELECT @msg = 'Deleting corrupt Organization record for "'+@sRDN+'" ('+STR(@sID)+') with duplicate GUID'
		PRINT @msg

		EXEC DeleteOrganization @sID
		FETCH NEXT FROM ou_cur INTO @sRDN, @sID
	END
	CLOSE ou_cur
	DEALLOCATE ou_cur

	-- Rename OUs. We loop, because if A->B and B->C, we must handle A
	-- specially. We could skip renaming A until B is done, but that
	-- would loop infinitely if A->B and B->A. So instead whenever a
	-- rename is blocked by an OU of the same name, we rename first to
	-- a temporary name. This guarantees that the loop will complete on
	-- the second pass. A slight optimization that's omitted because
	-- of complexity would be to only do a temporary rename when the
	-- current OU is both blocked and blocking another - the case is
	-- very infrequent and the cost low.
	SET @count = 1
	SET @loops = 0
	WHILE @count > 0 AND @loops < 10
	BEGIN
		SET @count = 0
		SET @loops = @loops + 1
		DECLARE ou_cur CURSOR FOR
			SELECT	o.OrganizationID,
				CASE WHEN EXISTS(
					SELECT * FROM Organization AS blocker
					WHERE	@DomainID = blocker.DomainID
					  AND	a.RDN = blocker.RDN
					  AND	a.GUID <> blocker.GUID
				) THEN	'OU=temp'+STR(RAND()*1000000000)
				ELSE	a.RDN
				END AS aRDN
			FROM	Organization AS o,
				ADSDOU AS a
			WHERE	@DomainID = o.DomainID
			  AND	@DomainID = a.DomainID
			  AND	o.GUID = a.GUID	-- Same OU
			  AND	ISNULL(o.RDN,'') <> ISNULL(a.RDN,'') -- Name chg
		OPEN ou_cur
		FETCH NEXT FROM ou_cur INTO @sID, @aRDN
		WHILE @@FETCH_STATUS = 0
		BEGIN
			SET @count = @count+1
			EXEC RenameOrganization @sID, @aRDN
			FETCH NEXT FROM ou_cur INTO @sID, @aRDN
		END
		CLOSE ou_cur
		DEALLOCATE ou_cur
	END

	IF @loops >= 10
	BEGIN
		SELECT @msg = 'Reconciliation of Organizations in '+DN+' failed to stabilize after 10 iterations'
			FROM Domain where OrganizationID = @DomainID
		PRINT @msg
	END

	-- Insert missing organizations into the table.
	INSERT Organization (DomainID, RDN, GUID, BlockInheritance)
		SELECT	@DomainID, RDN, GUID, BlockInheritance
		FROM	ADSDOU AS a
		WHERE	@DomainID = a.DomainID	-- From correct domain
		  AND	a.RDN <> ''
		  AND	NOT EXISTS(		-- Organization doesn't exist
				SELECT	*
				FROM	Organization AS o
				WHERE	a.GUID = o.GUID
				  AND	@DomainID = o.DomainID
			)

	-- Update all matching BlockInheritance values
	UPDATE o
		SET BlockInheritance = a.BlockInheritance
		FROM	Organization AS o,
			ADSDOU AS a
		WHERE	o.GUID = a.GUID
		  AND	o.BlockInheritance <> a.BlockInheritance
GO
/*
 * $Id: ReconcileUsers.sql 95296 2009-12-11 02:25:16Z rlowery $
 *
 * Reconcile the database with changes in one Active Directory Domain
 *
 * Protected by US patent 6,006,034; patents pending.
 * Copyright 2000-2002 ManageSoft Corporation. All rights reserved.
 * Reproduction, adaptation, or translation without prior permission
 * is prohibited.
 */
-- USE ManageSoft
GO

PRINT 'Creating procedure to reconcile Users with changes in an AD Domain'
IF EXISTS(SELECT * FROM sysobjects WHERE xtype = 'P'
	AND name = 'ReconcileUsers'
)
	DROP PROCEDURE ReconcileUsers
GO
CREATE PROCEDURE ReconcileUsers
	@DomainID	int,
	@Populate	BIT = 0,	-- Add all missing users
	@ParentOU	nvarchar(400) = NULL	-- not all users are in ADuser tables
AS
	DECLARE @count AS int
	DECLARE @loops AS int

	-- AD field values
	DECLARE @aGUID AS binary(16)
	DECLARE @aSAM AS varchar(20)
	DECLARE @aCN AS varchar(64)
	DECLARE @aOUID AS int		-- Organization ID of target OU
	DECLARE @aOU AS nvarchar(400)

	-- SQL field values
	DECLARE @sCN AS varchar(64)
	DECLARE @sSAM AS varchar(20)
	DECLARE @sOUID AS int		-- Organization ID
	DECLARE @sID AS INT
	DECLARE @bID AS INT		-- Blocking UserID
	DECLARE @bCN AS nvarchar(64)	-- Blocking User CN
	DECLARE @bSAM AS nvarchar(20)	-- Blocking User SAMAccountName
	DECLARE @bWontFix AS INT	-- Blocking User won't get fixed?

	DECLARE @newOUID AS INT		-- ID of new SD for moved user
	DECLARE @unknownOUID AS INT	-- ID of unknown OU in domain

	SELECT	@unknownOUID = OrganizationID
	FROM	Organization
	WHERE	DomainID = @DomainID
	  AND	RDN IS NULL

	-- Make sure that all matching DNs have their GUIDs set appropriately:
	EXEC PopulateUserGUIDs

	DECLARE @msg varchar(1024)
	SELECT @msg = 'Reconciling Users in '+DN+' with'+
		(CASE WHEN @Populate <> 1 THEN 'out' ELSE '' END) + ' populate'
		FROM Domain where OrganizationID = @DomainID
	PRINT @msg

	-- Delete Users whose GUIDs no longer exist:
	SELECT	u.UserID
	INTO	#User
	FROM	[User] AS u,
		Organization AS o
	WHERE	u.GUID IS NOT NULL
	  AND	u.UserOUID = o.OrganizationID
	  AND	o.DomainID = @DomainID
	  AND NOT EXISTS(
		SELECT * FROM ADUser AS a
		WHERE	@DomainID = a.DomainID
		  AND	u.GUID = a.GUID
		)
	  AND ISNULL(@ParentOU, '') = ''

	-- Delete Users with duplicate GUIDs. This should never
        -- happen, but databases have been known to become corrupted
        -- for one reason or another, and so we try to fix it up here
        -- by arbitrarily choosing one of the duplicates to be
        -- deleted.
	INSERT	#User(UserID)
	SELECT	u2.UserID
	FROM	[User] AS u1
		INNER JOIN [User] u2 ON u1.GUID = u2.GUID
	WHERE	u1.GUID IS NOT NULL
		AND u1.UserID < u2.UserID

	EXEC DeleteUsers
	DROP TABLE #User
	
	-- Now move any users in known OUs with NULL GUIDs to Unknown OU
	SELECT	u.UserID, @unknownOUID AS NewOUID
	INTO	#UsersToMove
	FROM	[User] AS u,
		Organization AS o
	WHERE (u.GUID IS NULL			-- With a NULL GUID
	  OR ( NOT ISNULL(@ParentOU, '') = ''
			AND RIGHT(o.RDN, LEN(@ParentOU)) = @ParentOU
			AND NOT EXISTS	-- GUID isn't already attached
				(SELECT * FROM ADUser AS adu WHERE u.GUID = adu.GUID)
		)
	  )
	  AND u.UserOUID = o.OrganizationID	-- Match organization
	  AND o.DomainID = @DomainID		-- In this domain
	  AND o.RDN IS NOT NULL			-- Not the unknown OU

	EXEC MoveUsersToNewOU
	TRUNCATE TABLE #UsersToMove

	-- Rename/Move users. We loop, because if A->B and B->C, we must
	-- handle A specially. We could skip renaming A until B is done, but
	-- that would loop infinitely if A->B and B->A. So instead whenever
	-- a rename is blocked by a user of the same name, we rename
	-- first to a temporary name. This guarantees that the loop will
	-- complete on the second pass. A slight optimization that's omitted
	-- because of complexity would be to only do a temporary rename when
	-- the current user is both blocked and blocking another - the
	-- case is very infrequent and the cost low.
	SET @count = 1
	SET @loops = 0
	WHILE @count > 0 AND @loops < 10
	BEGIN
		SET @count = 0
		SET @loops = @loops + 1
		DECLARE users CURSOR FOR
			SELECT	u.UserID,		-- This user
				u.UserOUID AS ActualOU, -- is here
				u.UserCN AS ActualCN,   -- called this
				u.SAMAccountName AS ActualSAM, -- but
				a.UserOUID AS TargetOU, -- should be here
				CASE WHEN ISNULL(cnBlocker.UserID, samBlocker.UserID) IS NOT NULL
					THEN	NULL
					ELSE	a.UserCN
				END AS TargetCN,
				CASE WHEN ISNULL(cnBlocker.UserID, samBlocker.UserID) IS NOT NULL
					THEN	NULL
					ELSE	a.SAMAccountName
				END AS TargetSAM,	-- called this
				ISNULL(cnBlocker.UserID, samBlocker.UserID) AS BlockerID,
				ISNULL(cnBlocker.UserCN, samBlocker.UserCN) AS BlockerCN,
				ISNULL(cnBlocker.SAMAccountName, samBlocker.SAMAccountName) AS BlockerSAM,
				CASE	WHEN ISNULL(cnBlocker.UserID, samBlocker.UserID) IS NOT NULL
						AND adBlocker.GUID IS NULL
					THEN 1
					ELSE 0
				END AS BlockerWontGetFixed
			FROM (		-- The Users we actually have
				SELECT	u.*
				FROM	[User] AS u,
					Organization AS o
				WHERE	@DomainID = o.DomainID
				  AND	o.OrganizationID = u.UserOUID
			     ) AS u
			     INNER JOIN
			     (		-- The Users we want
				SELECT	target_o.OrganizationID AS UserOUID,
					a.UserCN,
					a.SAMAccountName,
					a.GUID
				FROM	ADUser AS a
					INNER JOIN Organization AS target_o
					    ON a.UserOURDN = target_o.RDN
				WHERE	@DomainID = a.DomainID
				  AND	@DomainID = target_o.DomainID
			     ) AS a
				ON u.GUID = a.GUID	-- Same user
			     LEFT OUTER JOIN [User] cnBlocker
				 ON	u.UserID <> cnBlocker.UserID
				 AND	a.UserOUID = cnBlocker.UserOUID
				 AND	a.UserCN = cnBlocker.UserCN
			     LEFT OUTER JOIN [User] samBlocker
				 ON	u.UserID <> samBlocker.UserID
				 AND	a.UserOUID = samBlocker.UserOUID
				 AND	a.SAMAccountName = samBlocker.SAMAccountName
			     LEFT OUTER JOIN ADUser adBlocker
				 ON	adBlocker.GUID = ISNULL(cnBlocker.GUID, samBlocker.GUID)
			WHERE	u.UserOUID <> a.UserOUID -- Wrong place
				OR ISNULL(u.UserCN,'')	-- Wrong name
					<> ISNULL(a.UserCN,'')
				OR ISNULL(u.SAMAccountName,'')
					<> ISNULL(a.SAMAccountName,'')

		OPEN users
		FETCH NEXT FROM users INTO @sID, @sOUID, @sCN, @sSAM,
			@aOUID, @aCN, @aSAM, @bID, @bCN, @bSAM, @bWontFix
		WHILE @@FETCH_STATUS = 0
		BEGIN
			SET @count = @count+1

			IF @bWontFix = 1
			BEGIN
				-- We have a user blocking our rename that
				-- is not going to be moved/renamed within this
				-- loop: we have to take some drastic action to
				-- get it out of the way!

				IF EXISTS (
					SELECT	*
					FROM	[User] u
					WHERE	u.UserCN = @bCN
						AND u.UserOUID = @unknownOUID
				)
				OR EXISTS (
					SELECT	*
					FROM	[User] u
					WHERE	u.SAMAccountName = @bSAM
						AND u.UserOUID = @unknownOUID
				)
				BEGIN
					-- We've already got a user in the
					-- unknown OU with our blocker's name,
					-- so we can't just move the blocker
					-- in... We know that the blocker
					-- user must have been renamed (or
					-- deleted), but we don't know the
					-- details. So for now, we just give it
					-- a "temporary name". Future AD
					-- reconciles will fix this up.

					DECLARE @newName AS nvarchar(64)
					SET @newName = 'renamed'+STR(RAND()*1000000000)
					EXEC RenameUser @bID, @newName, @newName
				END

				INSERT INTO #UsersToMove(UserID, NewOUID)
				VALUES (@bID, @unknownOUID)
			END

			-- If User's in wrong OU, move it
			IF @sOUID <> @aOUID
			BEGIN
				INSERT INTO #UsersToMove(UserID, NewOUID)
				VALUES (@sID, @aOUID)
			END

			-- If User exists, but has wrong CN, fix it
			IF @aCN IS NULL
				SET @aCN = 'temp'+STR(RAND()*1000000000)

			IF @aSAM IS NULL
				SET @aSAM = 'tempsam'+STR(RAND()*1000000000)

			IF @aCN <> ISNULL(@sCN,'') OR @aSAM <> ISNULL(@sSAM,'')
				EXEC RenameUser @sID, @aCN, @aSAM

			FETCH NEXT FROM users INTO @sID, @sOUID, @sCN, @sSAM,
				@aOUID, @aCN, @aSAM, @bID, @bCN, @bSAM,
				@bWontFix
		END
		CLOSE users
		DEALLOCATE users
		
		EXEC MoveUsersToNewOU
		TRUNCATE TABLE #UsersToMove
	END

	IF @loops >= 10
	BEGIN
		SELECT @msg = 'Reconciliation of Users in '+DN+' failed to stabilize after 10 iterations'
			FROM Domain where OrganizationID = @DomainID
		PRINT @msg
	END

	-- Populate missing Users if requested
	IF @Populate <> 0
	BEGIN
		EXEC DomainUserPopulate @DomainID
	END

	-- Now go through the unknown OU to see if any users can be
	-- moved to their correct places.
	DECLARE user_cur CURSOR FOR
		SELECT	UserID, UserCN, SAMAccountName
		FROM	[User]
		WHERE	UserOUID = @unknownOUID
		  AND GUID IS NULL

	OPEN user_cur
	FETCH NEXT FROM user_cur INTO @sID, @sCN, @sSAM
	WHILE @@FETCH_STATUS = 0
	BEGIN
		IF (ISNULL(@sSAM, '') = '')	-- Default SAMAccountName
			SET @sSAM = @sCN

		-- N.B. If not found, variables retain *previous* value!
		SELECT @aCN = UserCN, @aOU = UserOURDN, @aGUID = GUID
			FROM ADUser
			WHERE SAMAccountName = @sSAM
				AND DomainID = @DomainID

		IF (@@ROWCOUNT = 1)
		BEGIN
			SELECT @aOUID = OrganizationID
				FROM Organization
				WHERE RDN = @aOU
				  AND DomainID = @DomainID

			IF (@@ROWCOUNT = 1 AND @aOUID IS NOT NULL)
			BEGIN
				-- Check that Target doesn't already exist
				IF EXISTS(
					SELECT * FROM [User]
					WHERE UserID <> @sID
					  AND (GUID = @aGUID
					   	OR (UserOUID = @aOUID
							AND UserCN = @sCN
						)
					)
				) BEGIN
					-- Target location/GUID for user is
					-- in use, delete unknown duplicate
					EXEC DeleteUser @sID
				END ELSE BEGIN
					UPDATE [User] SET GUID = @aGUID
						WHERE UserID = @sID
					INSERT INTO #UsersToMove(UserID, NewOUID)
					VALUES (@sID, @aOUID)
					IF (@aCN <> @sCN) BEGIN
						-- Fix CN, it's wrong:
						EXEC RenameUser @sID, @aCN, @sSAM
					END
				END
			END
		END

		FETCH NEXT FROM user_cur INTO @sID, @sCN, @sSAM
	END

	CLOSE user_cur
	DEALLOCATE user_cur
	
	EXEC MoveUsersToNewOU
	DROP TABLE #UsersToMove
GO



IF EXISTS(SELECT * FROM sysobjects WHERE xtype = 'P'
		AND name = 'ADUserReplaceSubsetByDomainID')
	DROP PROCEDURE ADUserReplaceSubsetByDomainID
IF EXISTS(SELECT * FROM sysobjects WHERE xtype = 'P'
		AND name = 'ADUserReplaceIndexedSubsetByDomainID')
	DROP PROCEDURE ADUserReplaceIndexedSubsetByDomainID
GO

-- Replace the record subset selected by (@DomainID)
-- using unique identifier (DomainID, UserCN, UserOURDN)
-- updating fields (GUID, SAMAccountName)
--
-- This procedure overrides the automatically generated procedure with
-- the addition of an index hint to use the TempADUserByDomainID
-- index. This is required because SQL Server seems to get its query
-- plan wrong by default for large sets of data without this. Note
-- that an index can't be created and then used in an index hint in
-- the same batch, so we create the index in
-- ADUserReplaceSubsetByDomainID, which then calls
-- ADUserReplaceIndexedSubsetByDomainID that uses the index.

CREATE PROCEDURE ADUserReplaceIndexedSubsetByDomainID
	@DomainID		int
AS
	DECLARE @count AS int
	SET @count = 0

	BEGIN TRANSACTION
	DELETE ADUser
		WHERE	DomainID = @DomainID
		AND NOT EXISTS(		-- Replacement record doesn't exist
			SELECT *
			FROM	#ADUser AS t WITH(INDEX(TempADUserByDomainID))
			WHERE	ADUser.DomainID = t.DomainID
			  AND	ADUser.UserCN = t.UserCN
			  AND	ADUser.UserOURDN = t.UserOURDN
		)

	UPDATE ADUser
		SET	GUID = t.GUID,
			SAMAccountName = t.SAMAccountName
		FROM	#ADUser AS t
		WHERE	ADUser.DomainID = t.DomainID
		  AND	ADUser.UserCN = t.UserCN
		  AND	ADUser.UserOURDN = t.UserOURDN
	SET @count = @@ROWCOUNT

	INSERT ADUser (
		DomainID,
		UserCN,
		UserOURDN,
		GUID,
		SAMAccountName
	)
		SELECT	DomainID,
			UserCN,
			UserOURDN,
			GUID,
			SAMAccountName
		FROM	#ADUser AS t
		WHERE NOT EXISTS(	-- Current record doesn't exist
			SELECT * FROM ADUser
			WHERE	ADUser.DomainID = t.DomainID
			  AND	ADUser.UserCN = t.UserCN
			  AND	ADUser.UserOURDN = t.UserOURDN
		)
	SET @count = @count + @@ROWCOUNT
	DROP TABLE #ADUser	-- Drop the temporary table
	COMMIT WORK
	RETURN @count
GO

CREATE PROCEDURE ADUserReplaceSubsetByDomainID
	@DomainID		int
AS
	CREATE INDEX [TempADUserByDomainID]
		ON #ADUser (DomainID, UserCN, UserOURDN)

	DECLARE @count AS int
	EXEC @count = ADUserReplaceIndexedSubsetByDomainID @DomainID

	RETURN @count
GO
/*
 * $Id: Reconcile.sql 84480 2007-07-24 06:34:27Z pca $
 *
 * Reconcile the database with changes in Active Directory
 *
 * Protected by US patent 6,006,034; patents pending.
 * Copyright 2000-2002 ManageSoft Corporation. All rights reserved.
 * Reproduction, adaptation, or translation without prior permission
 * is prohibited.
 */
-- USE ManageSoft
GO

/*--------------------------------------------------------------------------
 * Active Directory Load procedures
 *--------------------------------------------------------------------------*/
PRINT 'Creating procedure to reconcile changes in an AD Domain'
IF EXISTS(SELECT * FROM sysobjects WHERE xtype = 'P'
	AND name = 'ReconcileDomainNow'
)
	DROP PROCEDURE ReconcileDomainNow
GO
CREATE PROCEDURE ReconcileDomainNow
	@DomainID		INT,
	@TrialOnly		INT = 0,
	@PopulatePrincipals	BIT = 0,
	@ParentOU		nvarchar(400) = NULL,-- not all principals are in AD tables
	@ReconcileUsers		BIT = 1,
	@ReconcileComputers	BIT = 1
AS
	IF (@TrialOnly <> 0)
		BEGIN TRANSACTION

	EXEC ReconcileOrganizations @DomainID
	IF (@ReconcileComputers = 1)
		EXEC ReconcileComputers @DomainID, @PopulatePrincipals, @ParentOU
	IF (@ReconcileUsers = 1)
		EXEC ReconcileUsers @DomainID, @PopulatePrincipals, @ParentOU

	IF (@TrialOnly <> 0)
	BEGIN
		DECLARE	@msg varchar(1024)
		SELECT @msg = 'Rolling back work'
			 + ' during trial reconciliation of ' + DN
			FROM Domain WHERE OrganizationID = @DomainID
		PRINT @msg
		ROLLBACK WORK
	END ELSE
		UPDATE DomainConfiguration	-- Update Reconcile time + status
		SET 	Value = getdate(),
			DateValue = getdate(),
			LastUpdate = getdate()
		WHERE DomainID = @DomainID and Property = 'LastADReconcile'
GO
PRINT 'Creating procedure to update reconcile status'
IF EXISTS(SELECT * FROM sysobjects WHERE xtype = 'P'
	AND name = 'DomainUpdateADReconcileStatus'
)
	DROP PROCEDURE DomainUpdateADReconcileStatus
GO
CREATE PROCEDURE DomainUpdateADReconcileStatus
	@DomainID int,
	@Success bit
AS
	UPDATE Domain
	SET LastADReconcileStatus = @Success
	WHERE OrganizationID = @DomainID
GO
/*
 * $Id: UpdateInstallation.sql 94689 2009-11-09 00:38:57Z rlowery $
 *
 * Copyright 2000-2002 ManageSoft Corporation. All rights reserved.
 * Reproduction, adaptation, or translation without prior permission
 * is prohibited.
 */

-- USE ManageSoft

IF EXISTS(SELECT * from sysobjects WHERE xtype = 'P'
	AND name = 'UpdateInstallation'
)
	DROP PROCEDURE UpdateInstallation
GO

CREATE PROCEDURE UpdateInstallation
	@ComputerID		int,
	@ComputerOUID		int,
	@UserID			int,
	@UserOUID		int,
	@PackageFullName	nvarchar(256),
	@PackageName		nvarchar(64),
	@Version		nvarchar(32),
	@Action			varchar(10),
	@Reported		datetime,
	@FailReason		ntext,
	@Result			varchar(16),
	@Support5X		bit,
	@PostponePeriodStart	datetime = NULL,
	@PostponeNoLaterThan	datetime = NULL,
	@PolGUID		binary(16) = NULL,
	@PolName		nvarchar(512) = NULL,
	@PolVersion		int = NULL
AS BEGIN
	
	SET TRANSACTION ISOLATION LEVEL SERIALIZABLE 

	BEGIN TRANSACTION UpdateInstallationTran

	DECLARE @msg			varchar(1024)
	DECLARE @OUID			int
	DECLARE @PackageVersionID	int
	DECLARE @TempPackageName	nvarchar(64)
	DECLARE @TempVersion		nvarchar(32)
	DECLARE @TargetTypeId		int
	DECLARE @TargetId		int
	DECLARE	@FailReasonID		int

	-- Apply our new policy group membership if this was a install for a
	-- ManageSoft domain policy

	IF @PolGUID IS NOT NULL AND EXISTS(
		SELECT	*
		FROM	Domain
		WHERE	OrganizationID IN (
					SELECT	DomainID
					FROM	Policy
					WHERE	GUID = @PolGUID
				)
		  AND	DomainType = 'MGS'
	)
	BEGIN
		-- Delete any existing group memberships we may have
		DELETE
		FROM	Member
		WHERE	GroupID IN (
				SELECT	GroupID
				FROM	[Group]
				WHERE	GUID IN (
						SELECT	GUID
						FROM	Policy
						WHERE	DomainID IN (
								SELECT	OrganizationID
								FROM	Domain
								WHERE	DomainType = 'MGS'
							)
					)
				  AND	GUID <> @PolGUID
			)
		  AND	TargetID = CASE WHEN @UserID = 1 THEN @ComputerID ELSE @UserID END
		  AND	TargetTypeID = CASE WHEN @UserID = 1 THEN 1 ELSE 2 END

		-- Now add our new membership (our targetted policy)
		DECLARE @GroupID INT

		SELECT	@GroupID = GroupID
		FROM	[Group]
		WHERE	GUID = @PolGUID

		IF NOT EXISTS(
			SELECT	*
			FROM	Member
			WHERE	GroupID = @GroupID
			  AND	TargetTypeID = CASE WHEN @UserID = 1 THEN 1 ELSE 2 END
			  AND	TargetID = CASE WHEN @UserID = 1 THEN @ComputerID ELSE @UserID END
		)
		BEGIN
			INSERT INTO Member VALUES(
				@GroupID,
				CASE WHEN @UserID = 1 THEN 1 ELSE 2 END,
				CASE WHEN @UserID = 1 THEN @ComputerID ELSE @UserID END,
				1
			)
		END
	END

	SELECT	@OUID = CASE WHEN @UserID = 1 THEN @ComputerOUID ELSE @UserOUID END
	,	@TargetTypeId = CASE WHEN @UserID = 1 THEN 1 ELSE 2 END
	,	@TargetId = CASE WHEN @UserID = 1 THEN @ComputerID ELSE @UserID END

	IF @PackageFullName IS NOT NULL
	BEGIN
		-- See if we can find anything in the database
		-- matching exactly on the specified package full
		-- name, name and version
		SELECT	@PackageVersionID = v.PackageVersionID
		FROM	PackagePath p,
			PackageVersion v,
			PackageFamily f
		WHERE	@PackageFullName = p.PackageFullName
		  AND	@PackageName = f.PackageName
		  AND	@Version = v.Version
		  AND	p.PackagePathID = v.PackagePathID
		  AND	f.PackageFamilyID = v.PackageFamilyID
  
		IF @PackageVersionID IS NULL
  		BEGIN
			-- Nup, no exact match... Try to find a match
			-- just on package full name.
			--
			-- The variables in this SELECT statement get
			-- set to the LAST row returned by the query
			-- if there has been more than one package
			-- version at @PackageFullName. Hence with the
			-- ORDER BY clause given here, we prefer a
			-- package that is in the warehouse if there
			-- is one, but if not, we use the name and
			-- version of the package with the largest
			-- PackageVersionID (on the assumption that
			-- this package is the most "current").

			SELECT	@PackageVersionID = v.PackageVersionID,
				@PackageName = f.PackageName,
				@Version = v.Version
			FROM	PackagePath p,
				PackageVersion v
					LEFT OUTER JOIN MediaContainsPackageVersion mcpv
					ON mcpv.PackageVersionID = v.PackageVersionID
						AND mcpv.MediaID = 1, -- In warehouse
				PackageFamily f
			WHERE	@PackageFullName = p.PackageFullName
			  AND	p.PackagePathID = v.PackagePathID
			  AND	v.PackageFamilyID = f.PackageFamilyID
			ORDER BY mcpv.MediaID,	-- Will be NULL or 1, 1 last (preferred)
				v.PackageVersionID

			IF @@ROWCOUNT = 0
			BEGIN
				-- Package full name is unknown; add a
				-- new PackageVersion entry

				SET @PackageName = ISNULL(@PackageName, '')
				SET @Version = ISNULL(@Version, '')

				EXEC PackageVersionAddBound
					@PackageFullName,
					@Version,
					'',	-- Update
					@PackageName

				SELECT	@PackageVersionID = v.PackageVersionID
				FROM	PackagePath p,
					PackageFamily f,
					PackageVersion v
				WHERE	@PackageFullName = p.PackageFullName
				  AND	@PackageName = f.PackageName
				  AND	@Version = v.Version
				  AND	p.PackagePathID = v.PackagePathID
				  AND	f.PackageFamilyID = v.PackageFamilyID
			END
 		END
	END ELSE
	BEGIN
		-- Fetch PackageFullName from PackageVersion using
		-- Name/Version. Be aware that older versions of
		-- nDG/MGS didn't report PackageFullName, so this case
		-- is important for backwards compatibility.

		SELECT	@PackageVersionID = v.PackageVersionID,
			@PackageFullName = p.PackageFullName
		FROM	PackageVersion AS v,
			PackagePath AS p,
			PackageFamily AS f
		WHERE	@PackageName = f.PackageName
		  AND	@Version = v.Version
		  AND	p.PackagePathID = v.PackagePathID
		  AND	v.PackageFamilyID = f.PackageFamilyID

		IF @@ROWCOUNT = 0
		BEGIN
			DECLARE @forgePackageFullName nvarchar(256) 
			SET @forgePackageFullName = 'Installed/' + @PackageName
			
			SELECT	@PackageVersionID = v.PackageVersionID,
				@PackageFullName = p.PackageFullName
			FROM	PackageVersion AS v,
				PackagePath AS p
			WHERE	p.PackageFullName = @forgePackageFullName
			  AND	v.Version = @Version
			  AND	v.PackagePathID = p.PackagePathID

			-- If the package still cannot be located, add a
			-- package version entry with a synthetic PackagePath

			IF @@ROWCOUNT = 0
			BEGIN
				SET @PackageFullName = @forgePackageFullName

				EXEC PackageVersionAddBound
					@PackageFullName,
					@Version,
					'',	-- Update
					@PackageName

				SELECT	@PackageVersionID = v.PackageVersionID
				FROM PackageVersion AS v,
				     PackagePath AS p
				WHERE v.Version = @Version
				  AND p.PackageFullName = @PackageFullName
				  AND p.PackagePathID = v.PackagePathID
			END
		END
	END

	DECLARE @PackagePathID		int

	SELECT @PackagePathID = pp.PackagePathID
	FROM PackagePath AS pp
	WHERE pp.PackageFullName = @PackageFullName

	/*
	 * If the result type is 'postponed', we'll have to update the InstallationPostponement
	 * period details. Insert a new row if we must (a new row
	 * is needed if the log that is being processed now came from a client-side
	 * policy merge, and a server side policy merge have not occurred yet.)
	 */
	IF @Result = 'postponed'
	BEGIN
		-- Look for an existing postponement record, and the policy details:
		DECLARE	@AllocationDetailsID	int
		DECLARE	@ActualPolGUID		binary(16)
		DECLARE	@ExistingPostponement	datetime
		SELECT	TOP 1
			@ExistingPostponement = PostponePeriodStart,
			@AllocationDetailsID = AllocationDetailsID,
			@ActualPolGUID = PolicyGUID
		FROM	InstallationPostponement
		WHERE	TargetTypeID = @TargetTypeId
		  AND	TargetID = @TargetID
		  AND	PackagePathID = @PackagePathID
		  AND	(@PolGUID IS NULL OR PolicyGUID = @PolGUID)

		-- If a Postponement record is received as a result of a
		-- client-side policy merge before the server-side merge,
		-- has occurred, we have to fake up a policy record and
		-- AllocationDetails to attach the postponement to.
		IF @ExistingPostponement IS NULL -- no existing postponement
		AND @ActualPolGUID IS NULL	-- no policy is known
		BEGIN
			DECLARE @DomainID INT
			SELECT	@DomainID = DomainID
			FROM	Organization
			WHERE	OrganizationID = @OUID

			INSERT INTO Policy(
				GUID , DomainID , DisplayName
			) VALUES (
				@PolGUID , @DomainID,
				ISNULL(@PolName, 'New policy')
			)
			SET @ActualPolGUID = @PolGUID
		END

		IF @ExistingPostponement IS NULL -- no existing postponement
		AND @AllocationDetailsID IS NULL -- no PackageApplies is known
		BEGIN
			-- REVISIT: PackageAllocation might already exist. Check first?
			EXEC @AllocationDetailsID = AllocationDetailsBind
				@Action
				,NULL		-- EffectiveFrom
				,NULL		-- EffectiveFromIsLocal
				,NULL		-- EffectiveUntil
				,NULL		-- Wake
				,@PostponeNoLaterThan
				,0		-- PostponeNoLaterThanIsLocal
				,NULL		-- PostponePeriod
				,0		-- PostponeLatest
				,0		-- PostponeOKForLowBandwidth
				,1		-- PostponeOKForAnyReason
				,0		-- Exclusive
		END

		IF @ExistingPostponement IS NULL -- no existing postponement
			INSERT INTO InstallationPostponement(
				TargetTypeID
				,TargetID
				,PackagePathID
				,PolicyGUID
				,AllocationDetailsID
				,PostponePeriodStart
			)
			VALUES (
				@TargetTypeId
				,@TargetId
				,@PackagePathID
				,@ActualPolGUID
				,@AllocationDetailsID
				,@PostponePeriodStart
			)
	END -- if @Result = 'postponed'

	-- If necessary, bind the FailReason to the Reason table,
	-- using the SQL checksum of up to the first 4000 characters:
	IF @Result NOT IN ('rebootrequired', 'postponed')
	AND @FailReason IS NOT NULL AND LEN(CAST(@FailReason AS nvarchar(1))) > 0
	BEGIN
		SELECT	@FailReasonID = ReasonID
		FROM	Reason
		WHERE	ReasonHash = ISNULL(CHECKSUM(CAST(@FailReason AS nvarchar(4000))), 0)

		IF @FailReasonID IS NULL
		BEGIN
			INSERT Reason(ReasonText) VALUES (@FailReason)
			SET @FailReasonID = SCOPE_IDENTITY()
		END
	END

	-- No longer postponed, it's been installed:
	IF @Result IN ('success', 'notrequired', 'rebootrequired')
		DELETE	InstallationPostponement
		WHERE	TargetTypeID = @TargetTypeId
		  AND	TargetID = @TargetID
		  AND	PackagePathID = @PackagePathID

	IF LOWER(@ACTION) = 'uninstall'
	BEGIN
		IF @Result IN ('success', 'notrequired', 'rebootrequired')
			DELETE FROM Installation
			WHERE ComputerID = @ComputerID
			  AND UserID = @UserID
			  AND EXISTS (
				SELECT v.PackageVersionID
				FROM PackageVersion AS v, PackageFamily AS f
				WHERE Installation.PackageVersionID = v.PackageVersionID
				  AND f.PackageFamilyID = v.PackageFamilyID
				  AND f.PackageName = @PackageName
			  )
			  AND Reported < @Reported
	END ELSE BEGIN

		-- Delete older rows of any result, and
		-- insert new log only if no other rows, so if there
		-- is a more recent result, we keep that
		-- Also this is run for notrequired
		IF @FailReasonID IS NULL
		BEGIN
			DELETE FROM Installation
			WHERE ComputerID = @ComputerID
			AND UserID = @UserID
			AND PackageVersionID IN (
				SELECT v.PackageVersionID
				FROM PackageVersion AS v, PackageFamily AS f
				WHERE f.PackageName = @PackageName
				AND f.PackageFamilyID = v.PackageFamilyID
			)
			AND (	Reported < @Reported
				OR (	Reported = @Reported -- having datetime exactly the same
					AND ( -- the "rebootrequired" one should never override the "success" one
						Result <> 'success'
						OR @Result <> 'rebootrequired'
					)
				)		
			)
		END ELSE BEGIN
			-- For a failed install, only remove 
			-- existing install records for this version
			-- Previous version (may) still be installed.
			DELETE FROM Installation
			WHERE ComputerID = @ComputerID
			  AND UserID = @UserID
			  AND PackageVersionID IN (
				SELECT v.PackageVersionID
				FROM PackageVersion AS v, PackageFamily AS f
				WHERE f.PackageName = @PackageName
				  AND f.PackageFamilyID = v.PackageFamilyID
				  AND (v.Version = @Version
					OR Result NOT IN ('success', 'rebootrequired')
				)
			  )
			  AND (	Reported < @Reported
				OR (	Reported = @Reported
					AND (	-- having datetime exactly the same, the "rebootrequired" one should never override the "success" one
						Result <> 'success'
						OR @Result <> 'rebootrequired'
					)
				)		
			)

		END

		-- If there are no Installation records left for this @PackageName after the delete above, do an insert		
		IF NOT EXISTS 
		(
			SELECT ComputerID
			FROM Installation
			-- this repeats a fragment from the DELETE statement above
			WHERE ComputerID = @ComputerID
			  AND UserID = @UserID
			  AND PackageVersionID IN (
				SELECT	v.PackageVersionID
				FROM	PackageVersion AS v, PackageFamily AS f
				WHERE	f.PackageName = @PackageName
			 	  AND	f.PackageFamilyID = v.PackageFamilyID
			)
		)
		BEGIN
			-- At present, update, upgrade, downgrade etc are all installs
			-- installexs or installnes depending on the setting of Exclusive
			-- on the AllocationDetails (NULL, true, false respectively)

			-- Get the target's RSoP GroupID:
			DECLARE @RSoPGroupID	int
			SELECT	@RSoPGroupID = m.GroupID
			FROM	Member AS m, [Group] AS g
			WHERE	m.TargetTypeID = @TargetTypeID
			  AND	m.TargetID = @TargetID
			  AND	g.GroupCN = '+RSoP'
			  AND	m.GroupID = g.GroupID

			DECLARE @Exclusive	bit
			SELECT	@Exclusive = ad.Exclusive
			FROM	PackageApplies pa,
				AllocationDetails ad,
				PackagePath pp
			WHERE	pp.PackageFullName = @PackageFullName
			  AND	pp.PackagePathID = pa.PackagePathID
			  AND	pa.AllocationDetailsID = ad.AllocationDetailsID
			  AND	((pa.TargetTypeID = @TargetTypeID
				  AND TargetOUID = @OUID
				  AND TargetID = @TargetID)
			      OR (pa.TargetTypeID = 3 AND pa.TargetID = @RSoPGroupID)
				)

			SET @Action =
				CASE WHEN @Exclusive IS NULL THEN 'install'
				     WHEN @Exclusive = 1 THEN 'installex'
				     ELSE 'installne'
				END

			INSERT INTO Installation
				(ComputerID, UserID, OrganizationID,
				 PackageVersionID, Action,
				 Reported, FailReasonID, Result)
			VALUES 
				(@ComputerID, @UserID, @OUID,
				 @PackageVersionID, @Action,
				 @Reported, @FailReasonID,
				 @Result)
		END
	END

	-- Record the History in any case
	IF NOT EXISTS(
		SELECT	*
		FROM	InstallationHistory
		WHERE	ComputerID = @ComputerID
			AND UserID = @UserID
			AND PackageVersionID = @PackageVersionID
			AND Reported = @Reported
	)
		INSERT INTO InstallationHistory
			(ComputerID, UserID, PackageVersionID, Action,
			 Reported, FailReasonID, Result)
		VALUES 
			(@ComputerID, @UserID, @PackageVersionID, @Action,
			 @Reported, @FailReasonID,
			 @Result)
			 
			 
	COMMIT TRANSACTION UpdateInstallationTran			 
	
	SET TRANSACTION ISOLATION LEVEL READ COMMITTED  
			 
END
GO

IF EXISTS(SELECT * from sysobjects WHERE xtype = 'P'
	AND name = 'InstallationGetAllByDomainID'
)
	DROP PROCEDURE InstallationGetAllByDomainID
GO

CREATE PROCEDURE InstallationGetAllByDomainID
	@DomainID		int
AS BEGIN
	SELECT	i.ComputerID,
		i.UserID,
		i.PackageVersionID,
		i.OrganizationID,
		i.Action,
		i.Reported,
		i.Received,
		i.FailReasonID,
		i.Result
	FROM	Installation i,
		Organization o
	WHERE	i.OrganizationID = o.OrganizationID
	  AND	o.DomainID = @DomainID
	RETURN @@ROWCOUNT
END
GO
/*
 * $Id: BindToComputerAndUser.sql 90789 2008-12-18 22:40:25Z rlowery $
 *
 * After looking up Active Directory for a Computer and User, their GUIDs,
 * OUs and the GUIDs of the OUs, call this to find out or allocate the
 * SQL IDs (ComputerID, ComputerOUID, UserID, UserOUID) to associate with
 * those names.
 *
 * The returned recordset contains one row with the four output fields.
 * If any of the fields is NULL, the record could not be either found or
 * inserted.
 *
 * Copyright 2000-2002 ManageSoft Corporation. All rights reserved.
 * Reproduction, adaptation, or translation without prior permission
 * is prohibited.
 */

IF EXISTS(SELECT * from sysobjects WHERE xtype = 'P'
	AND name = 'BindToComputerAndUser'
)
	DROP PROCEDURE BindToComputerAndUser
GO
CREATE PROCEDURE BindToComputerAndUser
	@ComputerCN		nvarchar(64),
	@ComputerGUID		binary(16),
	@ComputerOURDN		nvarchar(400),
	@ComputerOUGUID		binary(16),
	@ComputerDomain		nvarchar(100),
	@ComputerFlatDomain	nvarchar(32),
	@PreferredComputerDC	nvarchar(20),
	@UserSAM		nvarchar(20),
	@UserCN			nvarchar(64),
	@UserGUID		binary(16),
	@UserOURDN		nvarchar(400),
	@UserOUGUID		binary(16),
	@UserDomain		nvarchar(100),
	@UserFlatDomain		nvarchar(32),
	@PreferredUserDC	nvarchar(20),
	@UseUniqueNames		INT
AS BEGIN
	DECLARE @ComputerDomainID INT
	DECLARE @ComputerDomainType varchar(4)
	DECLARE @UserDomainID INT
	DECLARE @UnknownID INT
	DECLARE @DomainOUID INT

	DECLARE @ComputerID INT
	DECLARE @ComputerOUID INT
	DECLARE @UserID INT
	DECLARE @UserOUID INT

	-- Convert ComputerOU to ComputerDomainID and ComputerOURDN
	IF LEN(@ComputerDomain) > 3
		SELECT @ComputerDomainID = OrganizationID, @ComputerDomainType = DomainType
			FROM Domain
			WHERE FlatName = SUBSTRING(@ComputerDomain, 4, LEN(@ComputerDomain) - 3) -- strip DC=

	IF @ComputerDomainID IS NULL		
		SELECT @ComputerDomainID = OrganizationID, @ComputerDomainType = DomainType
			FROM Domain
			WHERE DN = @ComputerDomain

	-- If domain doesn't exist, add it
	IF @ComputerDomainID IS NULL
		EXEC @ComputerDomainID = DomainCreate @ComputerDomain

	-- Set PreferredDomainController if specified
	IF @PreferredComputerDC IS NOT NULL
	BEGIN
		UPDATE Domain
		SET PreferredDomainController = @PreferredComputerDC
		WHERE OrganizationID = @ComputerDomainID
		AND PreferredDomainControllerOnly = 0
	END
	
	-- If flat domain name isn't set, populate it
	IF @ComputerFlatDomain IS NOT NULL
	BEGIN
		UPDATE Domain
			SET FlatName = @ComputerFlatDomain
			WHERE OrganizationID = @ComputerDomainID
			AND (FlatName IS NULL OR FlatName = '')
	END

	-- Get the unknown OU for this domain
	SELECT @UnknownID = OrganizationID
		FROM Organization
		WHERE RDN IS NULL
		  AND DomainID = @ComputerDomainID

	-- Get the OU for this domain
	SELECT @DomainOUID = OrganizationID
		FROM Organization
		WHERE RDN = ''
		  AND DomainID = @ComputerDomainID

	-- Look for the Computer first by GUID:
	IF @ComputerGUID IS NOT NULL
	BEGIN
		SELECT @ComputerID = ComputerID,
			@ComputerOUID = ComputerOUID
			FROM Computer
			WHERE GUID = @ComputerGUID
			ORDER by ComputerID DESC -- use first in case of dups
	END

	-- If not found by GUID, search by CN:
	IF @ComputerID IS NULL
	BEGIN
		-- PRINT 'Computer not found by GUID, trying CommonName'
		IF @ComputerDomainID IS NOT NULL
			SELECT	@ComputerID = c.ComputerID,
				@ComputerOUID = c.ComputerOUID
				FROM Computer as c, Organization as o
				WHERE @ComputerCN = c.ComputerCN
				  AND c.ComputerOUID = o.OrganizationID
				  AND o.DomainID = @ComputerDomainID

		IF @ComputerID IS NULL AND @UseUniqueNames = 1
			SELECT	@ComputerID = c.ComputerID,
				@ComputerOUID = c.ComputerOUID
				FROM Computer as c
				WHERE @ComputerCN = c.ComputerCN

		IF @ComputerID IS NOT NULL	-- We found it and
		AND @ComputerOUGUID IS NOT NULL	-- we know where it should be
		AND @ComputerGUID IS NOT NULL	-- Computer was found in AD
		BEGIN
			DECLARE	@NewComputerOUID int
			SELECT	@NewComputerOUID = OrganizationID
			FROM	Organization
			WHERE	@ComputerDomainID = DomainID
			  AND	@ComputerOUGUID = GUID
			  
			-- If Computer OU is still not found, insert it:
			IF @NewComputerOUID IS NULL
			AND @ComputerOURDN IS NOT NULL
			AND NOT EXISTS(		-- Some phoney blocking us :-(
				SELECT * FROM Organization
				WHERE	@ComputerDomainID = DomainID
				  AND	@ComputerOURDN = RDN
			)
			BEGIN
				INSERT INTO Organization(RDN, GUID, DomainID)
					VALUES (@ComputerOURDN, @ComputerOUGUID, @ComputerDomainID)
				SELECT @NewComputerOUID = OrganizationID	-- Fetch the new OUID
					FROM Organization
					WHERE GUID = @ComputerOUGUID
			END

			IF @NewComputerOUID IS NOT NULL	-- we know where it should be
			AND @ComputerOUID <> @NewComputerOUID	-- It's in the wrong place
			AND NOT EXISTS(		-- Some phoney blocking us :-(
				SELECT * FROM Computer
				WHERE	@ComputerCN = ComputerCN
				  AND	@NewComputerOUID = ComputerOUID
			)
			BEGIN
				-- Found by name in wrong OU, move it to the right place
				EXEC MoveComputerToNewOU @ComputerID, @NewComputerOUID
				SET @ComputerOUID = @NewComputerOUID
			END
			UPDATE Computer SET GUID = @ComputerGUID
				WHERE @ComputerID = ComputerID
		END
	END

	-- If Computer wasn't found, the OU might already exist anyway
	-- Search for it by GUID, then by name
	IF @ComputerOUID IS NULL
	AND @ComputerOUGUID IS NOT NULL
		SELECT @ComputerOUID = OrganizationID
			FROM Organization
			WHERE GUID = @ComputerOUGUID
	IF @ComputerOUID IS NULL
	AND @ComputerOURDN IS NOT NULL
		SELECT @ComputerOUID = OrganizationID
			FROM Organization
			WHERE RDN = @ComputerOURDN
			AND DomainID = @ComputerDomainID

	-- If Computer OU is still not found, insert it:
	IF @ComputerOUID IS NULL
	AND @ComputerOURDN IS NOT NULL
	AND @ComputerOUGUID IS NOT NULL
	BEGIN
		INSERT INTO Organization(RDN, GUID, DomainID)
			 VALUES (@ComputerOURDN, @ComputerOUGUID, @ComputerDomainID)
		SELECT @ComputerOUID = OrganizationID	-- Fetch the new OUID
			FROM Organization
			WHERE GUID = @ComputerOUGUID
	END

	-- If Computer OU still doesn't exist, it's the unknown OU
	IF @ComputerOUID IS NULL
	BEGIN
		IF @ComputerDomainType = 'AD'
			SET @ComputerOUID = @UnknownID
		ELSE
			SET @ComputerOUID = @DomainOUID
	END

	-- If Computer is still not found, insert a new one
	IF @ComputerID IS NULL
	AND (@ComputerOURDN IS NULL OR @ComputerGUID IS NOT NULL)
	BEGIN
		INSERT INTO Computer(ComputerCN, ComputerOUID, GUID)
			     VALUES (@ComputerCN, @ComputerOUID, @ComputerGUID)
		SELECT @ComputerID = ComputerID	    -- Fetch the new ComputerID
			FROM Computer
			WHERE ComputerCN = @ComputerCN
			  AND ComputerOUID = @ComputerOUID
	END
	IF @ComputerID IS NULL AND @ComputerOURDN IS NOT NULL
	BEGIN
		INSERT INTO Computer(ComputerCN, ComputerOUID)
			     VALUES (@ComputerCN, @ComputerOUID)
		SELECT @ComputerID = ComputerID
			FROM Computer
			WHERE ComputerCN = @ComputerCN
			  AND ComputerOUID = @ComputerOUID
	END

	-- Handle SYSTEM account first
	IF @UserSAM = 'system'
		SELECT @UserID = 1, @UserOUID = 1

	IF @UserID IS NULL	-- Not SYSTEM account
	BEGIN
		-- Convert UserOU to UserDomainID and UserOURDN
		IF LEN(@UserDomain) > 3
			SELECT @UserDomainID = OrganizationID
				FROM Domain
				WHERE FlatName = SUBSTRING(@UserDomain, 4, LEN(@UserDomain) - 3) -- strip DC=
			
		IF @UserDomainID IS NULL
			SELECT @UserDomainID = OrganizationID
				FROM Domain
				WHERE DN = @UserDomain

		-- If domain doesn't exist, add it
		IF @UserDomainID IS NULL
			EXEC @UserDomainID = DomainCreate @UserDomain

		-- Set PreferredDomainController if specified
		IF @PreferredUserDC IS NOT NULL
		BEGIN
			UPDATE Domain
			SET PreferredDomainController = @PreferredUserDC
			WHERE OrganizationID = @UserDomainID
			AND PreferredDomainControllerOnly = 0
		END

		-- If flat domain name isn't set, populate it
		IF @UserFlatDomain IS NOT NULL
		BEGIN
			UPDATE Domain
				SET FlatName = @UserFlatDomain
				WHERE OrganizationID = @UserDomainID
				AND (FlatName IS NULL OR FlatName = '')
		END

		-- Get the unknown OU for this domain
		SELECT @UnknownID = OrganizationID
			FROM Organization
			WHERE RDN IS NULL
			  AND DomainID = @UserDomainID
	END

	-- Look for User first by GUID:
	IF @UserID IS NULL AND @UserGUID IS NOT NULL
	BEGIN
		SELECT @UserID = UserID,
			@UserOUID = UserOUID
			FROM [User]
			WHERE GUID = @UserGUID
			ORDER by UserID DESC -- use last in case of dups
	END

	-- If not found by GUID, search by SAMAccountName
	IF @UserID IS NULL and @UserSAM IS NOT NULL
	BEGIN
		-- PRINT 'User not found by GUID, trying SAMAccountName'
		IF @UserDomainID IS NOT NULL
			SELECT @UserID = u.UserID,
				@UserOUID = u.UserOUID
				FROM [User] as u, Organization as o
				WHERE u.SAMAccountName = @UserSAM
				  AND u.UserOUID = o.OrganizationID
				  AND o.DomainID = @UserDomainID
			  
		IF @UserID IS NULL AND @UseUniqueNames = 1
	  		SELECT @UserID = u.UserID,
			@UserOUID = u.UserOUID
			FROM [User] as u
			WHERE u.SAMAccountName = @UserSAM
	END

	-- Short-circuit lookup for User OU if same as Computer OU:
	IF @UserOUID IS NULL
	AND @UserOURDN IS NOT NULL
	AND @UserOURDN = @ComputerOURDN
		SELECT @UserOUID = @ComputerOUID

	-- If User wasn't found, the OU might already exist anyway
	-- Search for it by GUID, then by name
	IF @UserOUID IS NULL
	AND @UserOUGUID IS NOT NULL
		SELECT @UserOUID = OrganizationID
			FROM Organization
			WHERE GUID = @UserOUGUID
	IF @UserOUID IS NULL
	AND @UserOURDN IS NOT NULL
		SELECT @UserOUID = OrganizationID
			FROM Organization
			WHERE RDN = @UserOURDN
			AND DomainID = @UserDomainID

	-- If UserOU is still not found, insert it:
	IF @UserOUID IS NULL
	AND @UserOUGUID IS NOT NULL
	BEGIN
		INSERT INTO Organization(RDN, GUID, DomainID)
			 VALUES (@UserOURDN, @UserOUGUID, @UserDomainID)
		SELECT @UserOUID = OrganizationID	-- Fetch the new OUID
			FROM Organization
			WHERE GUID = @UserOUGUID
	END

	-- If UserOU is still NULL, it's the unknown OU
	IF @UserOUID IS NULL
		SET @UserOUID = @UnknownID

	-- If User is still not found, insert a new one
	IF @UserID IS NULL
	AND (@UserOUID = @UnknownID OR @UserGUID IS NOT NULL)
	BEGIN
		INSERT INTO [User](SAMAccountName, UserCN, UserOUID, GUID)
			     VALUES (@UserSAM, @UserCN, @UserOUID, @UserGUID)
		SELECT @UserID = UserID		-- Fetch the new UserID
			FROM [User]
			WHERE SAMAccountName = @UserSAM
			  AND UserOUID = @UserOUID
	END

	-- Return the results:
	SELECT	ComputerID = @ComputerID,
		ComputerOUID = @ComputerOUID,
		UserID = @UserID,
		UserOUID = @UserOUID
END
GO

IF EXISTS(SELECT * from sysobjects WHERE xtype = 'P'
	AND name = 'BindFastToComputerAndUser'
)
	DROP PROCEDURE BindFastToComputerAndUser
GO
CREATE PROCEDURE BindFastToComputerAndUser
	@ComputerCN		nvarchar(64),
	@ComputerDomain		nvarchar(100),
	@UserSAM		nvarchar(20),
	@UserDomain		nvarchar(100),
	@UseUniqueNames		INT
AS BEGIN
	DECLARE @ComputerDomainID INT
	DECLARE @UserDomainID INT

	DECLARE @ComputerID INT
	DECLARE @ComputerOUID INT
	DECLARE @UserID INT
	DECLARE @UserOUID INT

	-- Convert ComputerOU to ComputerDomainID and ComputerOURDN
	IF LEN(@ComputerDomain) > 3
		SELECT @ComputerDomainID = OrganizationID
			FROM Domain
			WHERE FlatName = SUBSTRING(@ComputerDomain, 4, LEN(@ComputerDomain) - 3) -- strip DC=

	IF @ComputerDomainID IS NULL
		SELECT @ComputerDomainID = OrganizationID
			FROM Domain
			WHERE DN = @ComputerDomain

	IF @ComputerDomainID IS NOT NULL
		SELECT	@ComputerID = c.ComputerID,
			@ComputerOUID = c.ComputerOUID
			FROM Computer as c, Organization as o
			WHERE @ComputerCN = c.ComputerCN
			  AND c.ComputerOUID = o.OrganizationID
			  AND o.DomainID = @ComputerDomainID

	IF @ComputerID IS NULL AND @UseUniqueNames = 1
		SELECT	@ComputerID = c.ComputerID,
			@ComputerOUID = c.ComputerOUID
			FROM Computer as c
			WHERE @ComputerCN = c.ComputerCN

	-- Handle SYSTEM account first
	IF @UserSAM = 'system'
		SELECT @UserID = 1, @UserOUID = 1

	IF @UserID IS NULL and @UserSAM IS NOT NULL
	BEGIN
		-- Convert UserOU to UserDomainID and UserOURDN
		IF LEN(@UserDomain) > 3
			SELECT @UserDomainID = OrganizationID
				FROM Domain
				WHERE FlatName = SUBSTRING(@UserDomain, 4, LEN(@UserDomain) - 3) -- strip DC=
			
		IF @UserDomainID IS NULL
			SELECT @UserDomainID = OrganizationID
				FROM Domain
				WHERE DN = @UserDomain
		
		IF @UserDomainID IS NOT NULL
			SELECT @UserID = u.UserID,
				@UserOUID = u.UserOUID
				FROM [User] as u, Organization as o
				WHERE u.SAMAccountName = @UserSAM
				  AND u.UserOUID = o.OrganizationID
				  AND o.DomainID = @UserDomainID
	
		IF @UserID IS NULL AND @UseUniqueNames = 1
			SELECT @UserID = u.UserID,
				@UserOUID = u.UserOUID
				FROM [User] as u
				WHERE u.SAMAccountName = @UserSAM
	END

	-- Return the results:
	SELECT	ComputerID = @ComputerID,
		ComputerOUID = @ComputerOUID,
		UserID = @UserID,
		UserOUID = @UserOUID
END
GO
/*
 * $Id: UpdateUsageData.sql 90026 2008-10-29 00:58:01Z pca $
 *
 * Updates the SoftwareVersion table with details of new software.
 * The SoftwareID of the new software is returned.
 *
 * Copyright 2000-2002 ManageSoft Corporation. All rights reserved.
 * Reproduction, adaptation, or translation without prior permission
 * is prohibited.
 */
 
-- USE ManageSoft

PRINT 'Creating procedure to generate temp table for usage gathering.'
IF EXISTS(SELECT * from sysobjects WHERE xtype = 'P'
	AND name = 'SoftwareFileUsagePerWeekSchema'
)
	DROP PROCEDURE SoftwareFileUsagePerWeekSchema
GO
CREATE PROCEDURE SoftwareFileUsagePerWeekSchema
AS BEGIN

	SELECT
	'IF OBJECT_ID(''tempdb..#SoftwareUsagePerWeek'') IS NULL' +
	'	CREATE TABLE #SoftwareUsagePerWeek (' +
	'		SoftwareUsagePerWeekID	int NULL,' +
	'		ComputerID		int NOT NULL,' +
	'		UserID			int NOT NULL,' +
	'		SoftwareID		int NOT NULL,' +
	'		SoftwareFileNameID	int NULL,' +
	'		StartOfWeek		datetime NOT NULL,' +
	'		Duration		int NULL,' +
	'		ActiveTime		int NULL,' +
	'		Sessions		int NULL,' +
	'		Days			int NULL,' +
	'		Version			nvarchar(32) COLLATE database_default NULL,' +
	'		SoftwareFileUsageID	int NULL' +
	'	)' +
	'ELSE' +
	'	DELETE FROM #SoftwareUsagePerWeek' +
	'' AS SQL

END
GO

PRINT 'Creating procedure to update application usage data.'
IF EXISTS(SELECT * from sysobjects WHERE xtype = 'P'
	AND name = 'UpdateUsageData'
)
	DROP PROCEDURE UpdateUsageData
GO
CREATE PROCEDURE UpdateUsageData
AS BEGIN

--Update existing rows
UPDATE SoftwareUsagePerWeek
SET	SoftwareUsagePerWeek.Duration = SoftwareUsagePerWeek.Duration + t.Duration,
	SoftwareUsagePerWeek.ActiveTime = SoftwareUsagePerWeek.ActiveTime + t.ActiveTime,
	SoftwareUsagePerWeek.Sessions = SoftwareUsagePerWeek.Sessions + t.Sessions,
	SoftwareUsagePerWeek.Days = SoftwareUsagePerWeek.Days + t.Days
FROM #SoftwareUsagePerWeek AS t
WHERE SoftwareUsagePerWeek.ComputerID = t.ComputerID
	AND SoftwareUsagePerWeek.UserID = t.UserID
	AND SoftwareUsagePerWeek.SoftwareID = t.SoftwareID
	AND	(
			SoftwareUsagePerWeek.SoftwareFileUsageID = t.SoftwareFileUsageID OR
			(SoftwareUsagePerWeek.SoftwareFileUsageID IS NULL AND t.SoftwareFileUsageID IS NULL)
		)
	AND SoftwareUsagePerWeek.StartOfWeek = t.StartOfWeek


--Insert new rows
INSERT INTO SoftwareUsagePerWeek (ComputerID, UserID, SoftwareID, SoftwareFileUsageID, StartOfWeek, Duration, ActiveTime, Sessions, Days)
	--List of rows that are definitely new
	SELECT DISTINCT n.ComputerID AS ComputerID,
		n.UserID AS UserID,
		n.SoftwareID AS SoftwareID,
		n.SoftwareFileUsageID AS SoftwareFileUsageID,
		n.StartOfWeek AS StartOfWeek,
		n.Duration AS Duration,
		n.ActiveTime AS ActiveTime,
		n.Sessions AS Sessions,
		n.Days AS Days
	FROM #SoftwareUsagePerWeek AS n
	WHERE NOT EXISTS(
		SELECT *
		FROM SoftwareUsagePerWeek AS t
		WHERE t.ComputerID = n.ComputerID
		  AND t.UserID = n.UserID
		  AND t.StartOfWeek = n.StartOfWeek
		  AND t.SoftwareID = n.SoftwareID
		  AND  (
			t.SoftwareFileUsageID = n.SoftwareFileUsageID OR
			(t.SoftwareFileUsageID IS NULL AND n.SoftwareFileUsageID IS NULL)
		 )
		)

--Update the ComputerUsage table timestamp
UPDATE ComputerUsage
SET ComputerUsage.LastReported = final.LastReported
FROM (
	SELECT t.ComputerID AS ComputerID,
		t.UserID AS UserID,
		MAX(t.StartOfWeek) AS LastReported
	FROM #SoftwareUsagePerWeek AS t
	GROUP BY t.ComputerID, t.UserID

) AS final
	, ComputerUsage AS cu
WHERE final.ComputerID = cu.ComputerID
  AND final.UserID = cu.UserID
  AND final.LastReported > cu.LastReported

INSERT ComputerUsage
	SELECT final.ComputerID AS ComputerID
		,final.UserID AS UserID
		,final.LastReported AS LastReported
	FROM (
		SELECT t.ComputerID AS ComputerID,
			t.UserID AS UserID,
			MAX(t.StartOfWeek) AS LastReported
		FROM #SoftwareUsagePerWeek AS t
		GROUP BY t.ComputerID, t.UserID
	) AS final
	WHERE NOT EXISTS(
		SELECT *
		FROM ComputerUsage AS t
		WHERE t.ComputerID = final.ComputerID
		  AND t.UserID = final.UserID
	   )
	

--Drop the temporary table
DROP TABLE #SoftwareUsagePerWeek


END
GO
/*
 * $Id: UpdateSoftwareVersion.sql 45706 2002-12-11 01:12:21Z nvp $
 *
 * Updates the SoftwareVersion table with details of new software.
 * The SoftwareID of the new software is returned.
 *
 * Copyright 2000-2002 ManageSoft Corporation. All rights reserved.
 * Reproduction, adaptation, or translation without prior permission
 * is prohibited.
 */

-- USE MANAGESOFT
GO

PRINT 'Creating procedure to update the SoftwareVersion table'
IF EXISTS(SELECT * from sysobjects WHERE xtype = 'P'
	AND name = 'UpdateSoftwareVersion'
)
	DROP PROCEDURE UpdateSoftwareVersion
GO
CREATE PROCEDURE UpdateSoftwareVersion
	@SoftwareName nvarchar(128),
	@Version		varchar(32)
AS BEGIN

	IF NOT EXISTS
	(
		SELECT * FROM SoftwareVersion 
		WHERE SoftwareName = @SoftwareName
		AND Version = @Version
	)
	BEGIN
		INSERT INTO SoftwareVersion (SoftwareName, Version)
		VALUES (@SoftwareName, @Version)
	END

	SELECT SoftwareID FROM SoftwareVersion
	WHERE SoftwareName = @SoftwareName 
	AND Version = @Version
END
GO
-- USE ManageSoft
GO

PRINT 'Creating ComputerDN_to_ComputerCN_RDN_DomainDN procedure:'

IF EXISTS (
        SELECT * FROM dbo.sysobjects
        WHERE [name] = 'ComputerDN_to_ComputerCN_RDN_DomainDN' AND xtype = 'P'
)
        DROP PROCEDURE ComputerDN_to_ComputerCN_RDN_DomainDN
GO

CREATE PROCEDURE ComputerDN_to_ComputerCN_RDN_DomainDN
	@computerDN varchar(800),
	@computerCN varchar(800) OUTPUT,
	@RDN varchar(800) OUTPUT,
	@domainDN varchar(800) OUTPUT
AS
BEGIN
	DECLARE @indexrdn INT 
	DECLARE @indexdn INT 
	DECLARE @length INT

	SET @computerDN = LOWER(@computerDN)
	SET @indexrdn = CHARINDEX(',', @computerDN) + 1
	SET @indexdn = CHARINDEX('dc=', @computerDN)

	IF (@indexdn = 0)
		SET @indexdn = LEN(@computerDN) + 1

	IF (@indexrdn > 5)
		SET @computerCN = SUBSTRING(@computerDN, 4, @indexrdn - 5)
	ELSE
		SET @computerCN = ''

	IF (@indexdn = @indexrdn)
		SET @RDN = '%'
	ELSE IF (@indexdn = @indexrdn + 1)
		SET @RDN = SUBSTRING(@computerDN, @indexrdn, @indexdn - @indexrdn)
	ELSE
		SET @RDN = SUBSTRING(@computerDN, @indexrdn, @indexdn - @indexrdn - 1)
		
	SET @domainDN = SUBSTRING(@computerDN, @indexdn, 800)

	IF (@RDN = '%' AND @domainDN = '')
		SET @domainDN = '%'
END

GO

PRINT 'Creating mgsGetWakeOnLANHostInfo procedure:'

IF EXISTS (
	SELECT * FROM dbo.sysobjects
	WHERE [name] = 'mgsGetWakeOnLANHostInfo' AND xtype = 'P'
)
	DROP PROCEDURE mgsGetWakeOnLANHostInfo
GO

CREATE PROCEDURE [mgsGetWakeOnLANHostInfo]
	@computerDN VARCHAR(800)
AS
BEGIN
	DECLARE @computerCN VARCHAR(800)
	DECLARE @RDN VARCHAR(800)
	DECLARE @domainDN VARCHAR(800)
	EXEC ComputerDN_to_ComputerCN_RDN_DomainDN @computerDN, @computerCN OUTPUT, @RDN OUTPUT, @domainDN OUTPUT
	
	SELECT DISTINCT IP, NetMask, MAC FROM WakeOnLANHostInfo
	WHERE ComputerCN = @computerCN
	  AND RDN = @RDN
	  AND DomainDN = @domainDN
END
GO

PRINT 'Creating mgsAddWakeOnLANTask procedure:'

IF EXISTS (
	SELECT * FROM dbo.sysobjects
	WHERE [name] = 'mgsAddWakeOnLANTask' AND xtype = 'P'
)
	DROP PROCEDURE mgsAddWakeOnLANTask
GO

CREATE PROCEDURE [mgsAddWakeOnLANTask]
	@taskId BINARY(16),
	@friendlyName NVARCHAR(400),
	@dateTime DATETIME,
	@asap BIT
AS
BEGIN
	if @asap = 1
		INSERT WakeOnLANTask (TaskUID, FriendlyName) 
		VALUES (@taskId, @friendlyName)
	ELSE
		INSERT WakeOnLANTask 
		VALUES (@taskId, @friendlyName, @dateTime)
END
GO


PRINT 'Creating mgsRemoveWakeOnLANTask procedure:'

IF EXISTS (
	SELECT * FROM dbo.sysobjects
	WHERE [name] = 'mgsRemoveWakeOnLANTask' AND xtype = 'P'
)
	DROP PROCEDURE mgsRemoveWakeOnLANTask
GO

CREATE PROCEDURE [mgsRemoveWakeOnLANTask]
	@taskId BINARY(16)
AS
BEGIN
	-- remove managed device data
	DELETE	FROM WakeOnLANStatus 
	WHERE 	DistJobUID IN (
		SELECT 	DistJobUID from WakeOnLANDistributionJob
		WHERE 	TaskUID = @taskId
		)

	-- remove distribution job data
	DELETE	FROM WakeOnLANDistributionJob
	WHERE 	TaskUID = @taskId

	-- remove task data
	DELETE 	FROM WakeOnLANTask 
	WHERE 	TaskUID = @taskId
END
GO

PRINT 'Creating mgsAddWakeOnLANJob procedure:'

IF EXISTS (
	SELECT * FROM dbo.sysobjects
	WHERE [name] = 'mgsAddWakeOnLANJob' AND xtype = 'P'
)
	DROP PROCEDURE mgsAddWakeOnLANJob
GO

CREATE PROCEDURE [mgsAddWakeOnLANJob]
	@jobId BINARY(16),
	@taskId BINARY(16),
	@serverId BINARY(16)
AS
BEGIN
	INSERT INTO WakeOnLANDistributionJob VALUES (@jobId, @taskId, @serverId, 'Pending')
END
GO

PRINT 'Creating mgsUpdateWakeOnLANJob procedure:'

IF EXISTS (
	SELECT * FROM dbo.sysobjects
	WHERE [name] = 'mgsUpdateWakeOnLANJob' AND xtype = 'P'
)
	DROP PROCEDURE mgsUpdateWakeOnLANJob
GO

CREATE PROCEDURE [mgsUpdateWakeOnLANJob]
	@jobId BINARY(16),
	@status VARCHAR(16)
AS
BEGIN
	UPDATE WakeOnLANDistributionJob SET State = @status
	WHERE DistJobUID = @jobId
END
GO

PRINT 'Creating mgsAddWakeOnLANStatus procedure:'

IF EXISTS (
	SELECT * FROM dbo.sysobjects
	WHERE [name] = 'mgsAddWakeOnLANStatus' AND xtype = 'P'
)
	DROP PROCEDURE mgsAddWakeOnLANStatus
GO

CREATE PROCEDURE [mgsAddWakeOnLANStatus]
	@computerDN VARCHAR(800),
	@jobId BINARY(16)
AS
BEGIN
	DECLARE @entries INT
	DECLARE @computerCN VARCHAR(800)
	DECLARE @RDN VARCHAR(800)
	DECLARE @domainDN VARCHAR(800)
	EXEC ComputerDN_to_ComputerCN_RDN_DomainDN @computerDN, @computerCN OUTPUT, @RDN OUTPUT, @domainDN OUTPUT

	-- check for duplicates and ignore them
	-- duplicates occur if a computer has two
	-- configured network adapters. 
	-- We try Wake On LAN on both adapters but
	-- only want a single status
	SELECT	@entries = COUNT(*)
	FROM	WakeOnLANStatus as w,
		WakeOnLanHostInfo as h
	WHERE	DistJobUID = @jobId
	  AND	h.ComputerID = w.ComputerID
	  AND	h.ComputerCN = @computerCN
	  AND	h.RDN = @RDN
	  AND	h.DomainDN = @domainDN


	IF @entries = 0
	BEGIN
		INSERT	INTO WakeOnLANStatus
			SELECT DISTINCT @jobId, w.ComputerID, 'Pending'
			FROM	WakeOnLANHostInfo AS w
			WHERE	w.ComputerCN = @computerCN
			  AND	w.RDN = @RDN
			  AND	w.DomainDN = @domainDN
	END
END
GO

PRINT 'Creating mgsUpdateWakeOnLANStatus procedure:'

IF EXISTS (
	SELECT * FROM dbo.sysobjects
	WHERE [name] = 'mgsUpdateWakeOnLANStatus' AND xtype = 'P'
)
	DROP PROCEDURE mgsUpdateWakeOnLANStatus
GO

CREATE PROCEDURE [mgsUpdateWakeOnLANStatus]
	@computerDN VARCHAR(800),
	@jobId BINARY(16),
	@status VARCHAR(16)
AS
BEGIN
	DECLARE @computerCN VARCHAR(800)
	DECLARE @RDN VARCHAR(800)
	DECLARE @domainDN VARCHAR(800)
	EXEC ComputerDN_to_ComputerCN_RDN_DomainDN @computerDN, @computerCN OUTPUT, @RDN OUTPUT, @domainDN OUTPUT

	UPDATE	WakeOnLANStatus SET State = @status
	FROM	WakeOnLANStatus as w,
		Computer as c,
		Organization as o,
		Domain as d
	WHERE	DistJobUID = @jobId
	  AND	w.ComputerID = c.ComputerID
	  AND	c.ComputerOUID = o.OrganizationID
	  AND	o.DomainID = d.OrganizationID
	  AND	c.ComputerCN LIKE @ComputerCN
	  AND	o.RDN LIKE @RDN
	  AND	d.DN LIKE @domainDN

	UPDATE WakeOnLANDistributionJob SET State = 'Success'
	WHERE DistJobUID = @jobId
END
GO
/*
 * $Id: Packaging.sql 84480 2007-07-24 06:34:27Z pca $
 *
 * Stored Procedures for managing the Packaging tables
 *
 * Protected by US patent 6,006,034; patents pending.
 * Copyright 2000-2002 ManageSoft Corporation. All rights reserved.
 * Reproduction, adaptation, or translation without prior permission
 * is prohibited.
 */

PRINT 'Creating procedure to update PackageVersion in Warehouse'
IF EXISTS(SELECT * FROM sysobjects WHERE xtype = 'P'
	AND name = 'PackageVersionUpdateWarehouse'
)
	DROP PROCEDURE PackageVersionUpdateWarehouse
GO
CREATE PROCEDURE PackageVersionUpdateWarehouse
	@PackageFullName	nvarchar(256),
	@Version		nvarchar(32),
	@PackageName		nvarchar(64),
	@Title			nvarchar(64),
	@PackageType		nvarchar(128) = 'Unknown',
	@MD5			nvarchar(40),
	@BasePackage		nvarchar(256) = NULL,
	@Size			int = NULL,
	@PackageStateID		int = 1,
	@OverwriteUserPackageState bit = 1

AS BEGIN
	BEGIN TRANSACTION

	-- Delete any record of any Version of this PackagePath in the Warehouse
	DELETE	MediaContainsPackageVersion
	FROM	PackageVersion AS v,
		PackagePath AS p
	WHERE	MediaContainsPackageVersion.MediaID = 1	-- Local Warehouse
	  AND	MediaContainsPackageVersion.PackageVersionID = v.PackageVersionID
	  AND	v.PackagePathID = p.PackagePathID
	  AND	p.PackageFullName = @PackageFullName

	-- Delete record in MediaContainsPackagePath in this Warehouse
	DELETE	MediaContainsPackagePath
	FROM	PackageVersion AS v,
		PackagePath AS p
	WHERE	MediaContainsPackagePath.MediaID = 1	-- Local Warehouse
	  AND	MediaContainsPackagePath.PackagePathID = p.PackagePathID
	  AND	v.PackagePathID = p.PackagePathID
	  AND	p.PackageFullName = @PackageFullName

	DECLARE @PackageFamilyID int
	DECLARE @PackagePathID int
	DECLARE @PackageVersionID int
	DECLARE @PackagePathTypeID int
	DECLARE @ParentPathID int
	
	-- Default PackagePathTypeID to unknown
	Set @PackagePathTypeID = 1

	SELECT @PackagePathTypeID = PackagePathTypeID 
	FROM PackagePathType 
	WHERE Description = @PackageType

	-- Populate parent folder first
	IF (@BasePackage IS NOT NULL And LEN(@BasePackage) > 0)
	BEGIN
	
		SELECT @ParentPathID = PackagePathID 
		FROM PackagePath
		WHERE PackageFullName = @BasePackage
		
	END
	ELSE BEGIN
		EXEC @ParentPathID = PackagePathAddFolders @PackageFullName

		IF @ParentPathID = 0
			SET @ParentPathID = NULL
	END

	EXEC @PackagePathID = PackagePathBind @PackageFullName, @ParentPathID, @PackagePathTypeID 

	IF NOT EXISTS(
		SELECT	PackagePathTypeID
		FROM	PackagePath
		WHERE	PackagePathID = @PackagePathID
		  AND	PackagePathTypeID = @PackagePathTypeID
	)
	BEGIN
		-- Update the package path type ID
		UPDATE	PackagePath
		SET	PackagePathTypeID = @PackagePathTypeID
		WHERE	PackagePathID = @PackagePathID
	END

	EXEC @PackageFamilyID = PackageFamilyBind @PackageName

	SELECT @PackageVersionID = PackageVersionID
	FROM PackageVersion AS v, PackagePath AS p
	WHERE p.PackageFullName = @PackageFullName
	  AND v.PackagePathID = p.PackagePathID
	  AND v.Version = @Version

	IF @@ROWCOUNT = 1
	BEGIN
		-- An existing Package with this Version is in the database
		IF @Size IS NULL
		BEGIN
			UPDATE PackageVersion
			SET	PackageFamilyID = @PackageFamilyID,
				Title = @Title,
				MD5 = @MD5
			WHERE	PackageVersionID = @PackageVersionID
		END
		ELSE BEGIN
			UPDATE PackageVersion
			SET	PackageFamilyID = @PackageFamilyID,
				Title = @Title,
				MD5 = @MD5,
				Size = @Size
			WHERE	PackageVersionID = @PackageVersionID
		END	
	END
	ELSE BEGIN
		INSERT PackageVersion
			(PackagePathID, Version, PackageFamilyID,
				Title, MD5, Size)
		VALUES	(@PackagePathID, @Version, @PackageFamilyID,
				@Title, @MD5, @Size)

		-- Get the PackageVersionID for the new PackageVersion
		SELECT	@PackageVersionID = PackageVersionID
		FROM	PackageVersion
		WHERE	PackagePathID = @PackagePathID
		  AND	Version = @Version
	END

	-- Update the Warehouse's MediaContainsPackageVersion for this Package
	INSERT MediaContainsPackageVersion (MediaID, PackageVersionID)
	VALUES (1, @PackageVersionID)

	-- Update the Warehouse's MediaContainsPackagePath for this Package
	INSERT MediaContainsPackagePath (MediaID, PackagePathID)
	VALUES (1, @PackagePathID)

	-- Set the default state for the PackageVersion (if there is no existing state)
	IF (@PackageStateID IS NOT NULL)
	BEGIN
		-- Get the 'current' state
		DECLARE @username nvarchar(256)
		DECLARE @changed datetime
		SELECT TOP 1 @username=username, @changed=changed
		FROM PackageVersionInState pvis
		WHERE pvis.PackageVersionID = @PackageVersionID
		ORDER BY Changed DESC
		IF @@ROWCOUNT = 1 AND @username = ''
		BEGIN
			-- If it was set by the system (no username)
			-- then simply update
			UPDATE 	PackageVersionInState
			SET		PackageStateID = @PackageStateID,
					changed = getdate()
			WHERE	username = @username
			AND		changed = @changed
		END
		ELSE BEGIN
			IF @@ROWCOUNT = 0 OR @OverwriteUserPackageState = 1
			BEGIN
				-- If it was set by a user, then insert a new record
				INSERT PackageVersionInState (PackageVersionID, PackageStateID, UserName, Changed, Comments)
				VALUES (@PackageVersionID, @PackageStateID, '', getdate(), '')
			END
		END
	END
		
	COMMIT
END
GO


PRINT 'Creating procedure to update PackageVersion in Warehouse'
IF EXISTS(SELECT * FROM sysobjects WHERE xtype = 'P'
	AND name = 'PackageVersionUpdateWarehouseWithCategoryUpdate'
)
	DROP PROCEDURE PackageVersionUpdateWarehouseWithCategoryUpdate
GO
CREATE PROCEDURE PackageVersionUpdateWarehouseWithCategoryUpdate
	@PackageFullName	nvarchar(256),
	@Version		nvarchar(32),
	@PackageName		nvarchar(64),
	@Update			nvarchar(64),
	@Category		nvarchar(128),
	@Title			nvarchar(64),
	@PackageType		nvarchar(128),
	@MD5			nvarchar(40) = NULL,
	@Size			int = NULL
AS BEGIN
	BEGIN TRANSACTION

	-- Delete any record of any Version of this PackagePath in the Warehouse
	DELETE	MediaContainsPackageVersion
	FROM	PackageVersion AS v,
		PackagePath AS p
	WHERE	MediaContainsPackageVersion.MediaID = 1	-- Local Warehouse
	  AND	MediaContainsPackageVersion.PackageVersionID = v.PackageVersionID
	  AND	v.PackagePathID = p.PackagePathID
	  AND	p.PackageFullName = @PackageFullName

	-- Delete record in MediaContainsPackagePath in this Warehouse
	DELETE	MediaContainsPackagePath
	FROM	PackageVersion AS v,
		PackagePath AS p
	WHERE	MediaContainsPackagePath.MediaID = 1	-- Local Warehouse
	  AND	MediaContainsPackagePath.PackagePathID = p.PackagePathID
	  AND	v.PackagePathID = p.PackagePathID
	  AND	p.PackageFullName = @PackageFullName


	DECLARE @PackageFamilyID int
	DECLARE @PackagePathID int
	DECLARE @PackageVersionID int
	DECLARE @PackagePathTypeID int
	DECLARE @ParentPathID int
	
	-- Default PackagePathTypeID to unknown
	Set @PackagePathTypeID = 1

	SELECT @PackagePathTypeID = PackagePathTypeID 
	FROM PackagePathType 
	WHERE Description = @PackageType

	EXEC @ParentPathID = PackagePathAddFolders @PackageFullName
	
	IF @ParentPathID = 0
		SET @ParentPathID = NULL
		
	EXEC @PackagePathID = PackagePathBind @PackageFullName, @ParentPathID, @PackagePathTypeID

	IF NOT EXISTS(
		SELECT	PackagePathTypeID
		FROM	PackagePath
		WHERE	PackagePathID = @PackagePathID
		  AND	PackagePathTypeID = @PackagePathTypeID
	)
	BEGIN
		-- Update the package path type ID
		UPDATE	PackagePath
		SET	PackagePathTypeID = @PackagePathTypeID
		WHERE	PackagePathID = @PackagePathID
	END

	EXEC @PackageFamilyID = PackageFamilyBind @PackageName

	SELECT @PackageVersionID = PackageVersionID
	FROM PackageVersion AS v, PackagePath AS p
	WHERE p.PackageFullName = @PackageFullName
	  AND v.PackagePathID = p.PackagePathID
	  AND v.Version = @Version
	  AND v.[Update] = @Update

	IF @@ROWCOUNT = 1
	BEGIN
		-- An existing Package with this Version is in the database
		IF @Size IS NULL
		BEGIN
			UPDATE PackageVersion
			SET	PackageFamilyID = @PackageFamilyID,
				Title = @Title,
				MD5 = @MD5,
				[Update] = @Update,
				Category = @Category
			WHERE	PackageVersionID = @PackageVersionID
		END
		ELSE BEGIN
			UPDATE PackageVersion
			SET	PackageFamilyID = @PackageFamilyID,
				Title = @Title,
				MD5 = @MD5,
				Size = @Size,
				[Update] = @Update,
				Category = @Category
			WHERE	PackageVersionID = @PackageVersionID
		END
	END
	ELSE BEGIN
		INSERT PackageVersion
			(PackagePathID, Version, PackageFamilyID,
				Title, MD5, Size,
				[Update], Category)
		VALUES	(@PackagePathID, @Version, @PackageFamilyID,
				@Title, @MD5, @Size,
				@Update, @Category)

		-- Get the PackageVersionID for the new PackageVersion
		SELECT	@PackageVersionID = PackageVersionID
		FROM	PackageVersion
		WHERE	PackagePathID = @PackagePathID
		  AND	Version = @Version
		  AND	[Update] = @Update
		  AND	PackageFamilyID = @PackageFamilyID
	END

	-- Update the Warehouse's MediaContainsPackageVersion for this Package
	INSERT MediaContainsPackageVersion (MediaID, PackageVersionID)
	VALUES (1, @PackageVersionID)

	-- Update the Warehouse's MediaContainsPackagePath for this Package
	INSERT MediaContainsPackagePath (MediaID, PackagePathID)
	VALUES (1, @PackagePathID)

	COMMIT
END
GO

PRINT 'Creating procedure to update MD5 of PackageVersion in Warehouse'
IF EXISTS(SELECT * FROM sysobjects WHERE xtype = 'P'
	AND [name] = 'PackageVersionUpdateMD5'
)
	DROP PROCEDURE PackageVersionUpdateMD5
GO
CREATE PROCEDURE PackageVersionUpdateMD5
	@packageFullName NVARCHAR(256),
	@md5 NVARCHAR(40)
AS
	UPDATE	[PackageVersion]
	SET	MD5 = @md5
	FROM	MediaContainsPackageVersion AS mcp,
		PackagePath AS p
	WHERE	PackageVersion.PackagePathID = p.PackagePathID
	  AND	p.PackageFullName = @packageFullName
	  AND	PackageVersion.PackageVersionID	= mcp.PackageVersionID
	  AND	mcp.MediaID = 1		-- Warehouse
GO

PRINT 'Creating procedure to remove PackageVersion from Warehouse'
IF EXISTS(SELECT * FROM sysobjects WHERE xtype = 'P'
	AND name = 'PackageVersionRemoveWarehouse'
)
	DROP PROCEDURE PackageVersionRemoveWarehouse
GO
CREATE PROCEDURE PackageVersionRemoveWarehouse
	@PackageFullName	nvarchar(256)
AS BEGIN
	DELETE MediaContainsPackageVersion
	FROM	PackageVersion AS v,
		PackagePath AS p
	WHERE MediaContainsPackageVersion.MediaID = 1
	  AND MediaContainsPackageVersion.PackageVersionID = v.PackageVersionID
	  AND v.PackagePathID = p.PackagePathID
	  AND p.PackageFullName = @PackageFullName

	DELETE	MediaContainsPackagePath
	FROM	PackageVersion AS v,
		PackagePath AS p
	WHERE	MediaContainsPackagePath.MediaID = 1	-- Local Warehouse
	  AND	MediaContainsPackagePath.PackagePathID = p.PackagePathID
	  AND	v.PackagePathID = p.PackagePathID
	  AND	p.PackageFullName = @PackageFullName

	-- Remove the package and its parent folder from MediaContainsPackagePath
	EXEC MediaContainsPackagePathRemoveByPackageFullName @PackageFullName

	-- Remove package state history when removed from the software lib.
	DELETE 	PackageVersionInState
	FROM	PackageVersionInState AS pvis,
		PackageVersion AS v,
		PackagePath AS p
	WHERE	pvis.PackageversionID = v.PackageVersionID
	AND	v.PackagePathID = p.PackagePathID
	AND 	p.PackageFullName = @PackageFullName

END
GO

IF EXISTS(SELECT * FROM sysobjects WHERE xtype = 'P'
	AND name = 'PackageVersionAddBound'
)
	DROP PROCEDURE PackageVersionAddBound
GO
CREATE PROCEDURE PackageVersionAddBound
	@PackageFullName	nvarchar(256),
	@Version		nvarchar(32),
	@Update			nvarchar(64) = NULL,
	@PackageName		nvarchar(64),
	@Title			nvarchar(64) = NULL,
	@MD5			nvarchar(40) = NULL,
	@Size			int = NULL,
	@Category		nvarchar(128) = NULL,
	@PackageType		nvarchar(128) = NULL
AS BEGIN
	DECLARE @PackagePathID int
	DECLARE @PackageFamilyID int
	DECLARE @PackagePathTypeID int
	DECLARE @ParentPathID int
	
	-- Default PackagePathTypeID to unknown
	Set @PackagePathTypeID = 1

	SELECT @PackagePathTypeID = PackagePathTypeID 
	FROM PackagePathType 
	WHERE Description = @PackageType

	EXEC @ParentPathID = PackagePathAddFolders @PackageFullName

	IF @ParentPathID = 0
		SET @ParentPathID = NULL

	EXEC @PackagePathID = PackagePathBind @PackageFullName, @ParentPathID, @PackagePathTypeID

	IF NOT EXISTS(
		SELECT	PackagePathTypeID
		FROM	PackagePath
		WHERE	PackagePathID = @PackagePathID
		  AND	PackagePathTypeID = @PackagePathTypeID
	)
	BEGIN
		-- Update the package path type ID
		UPDATE	PackagePath
		SET	PackagePathTypeID = @PackagePathTypeID
		WHERE	PackagePathID = @PackagePathID
	END

	EXEC @PackageFamilyID = PackageFamilyBind @PackageName

	EXEC PackageVersionAdd
			@PackagePathID,
			@Version,
			@Update,
			@PackageFamilyID,
			@Title,
			@MD5,
			@Size,
			@Category
END
GO

IF EXISTS(SELECT * FROM sysobjects WHERE xtype = 'P'
	AND name = 'PackageVersionBindBound'
)
	DROP PROCEDURE PackageVersionBindBound
GO
CREATE PROCEDURE PackageVersionBindBound
	@PackageFullName	nvarchar(256),
	@Version		nvarchar(32),
	@Update			nvarchar(64) = NULL,
	@PackageName		nvarchar(64),
	@PackageType		nvarchar(128),
	@Title			nvarchar(64) = NULL,
	@MD5			nvarchar(40) = NULL,
	@Size			int = NULL,
	@Category		nvarchar(128) = NULL
AS BEGIN
	DECLARE @PackagePathID int
	DECLARE @PackageFamilyID int
	DECLARE @PackageVersionID int
	DECLARE @PackagePathTypeID int
	DECLARE @ParentPathID int
	
	-- Default PackagePathTypeID to unknown
	Set @PackagePathTypeID = 1

	SELECT @PackagePathTypeID = PackagePathTypeID 
	FROM PackagePathType 
	WHERE Description = @PackageType

	EXEC @ParentPathID = PackagePathAddFolders @PackageFullName

	IF @ParentPathID = 0
		SET @ParentPathID = NULL
		
	EXEC @PackagePathID = PackagePathBind @PackageFullName, @ParentPathID, @PackagePathTypeID

	IF NOT EXISTS(
		SELECT	PackagePathTypeID
		FROM	PackagePath
		WHERE	PackagePathID = @PackagePathID
		  AND	PackagePathTypeID = @PackagePathTypeID
	)
	BEGIN
		-- Update the package path type ID
		UPDATE	PackagePath
		SET	PackagePathTypeID = @PackagePathTypeID
		WHERE	PackagePathID = @PackagePathID
	END

	EXEC @PackageFamilyID = PackageFamilyBind @PackageName

	EXEC @PackageVersionId = PackageVersionBind
			@PackagePathID,
			@Version,
			@Update,
			@PackageFamilyID,
			@Title,
			@MD5,
			@Size,
			@Category

	RETURN	@PackageVersionID
END
GO

IF EXISTS(SELECT * FROM sysobjects WHERE xtype = 'P'
	AND name = 'PackageVersionGetLatestVersionAndFamilyByPackageFullName'
)
	DROP PROCEDURE PackageVersionGetLatestVersionAndFamilyByPackageFullName
GO
CREATE PROCEDURE PackageVersionGetLatestVersionAndFamilyByPackageFullName
	@PackageFullName	nvarchar(256)
AS BEGIN
	SELECT MAX(pv.Version) AS LatestVersion, pf.PackageName AS PackageFamily
	FROM   PackageVersion AS pv,
	       PackageFamily AS pf,
	       PackagePath AS pp
	WHERE  pv.PackagePathID = pp.PackagePathID
	  ANd  pv.PackageFamilyID = pf.PackageFamilyID
	  AND  pp.PackageFullName = @PackageFullName
	GROUP BY pf.PackageName

	RETURN @@ROWCOUNT
END
GO

PRINT 'Creating procedure to get the latest existing PackageVersions by PackagePathID'
IF EXISTS(SELECT * FROM sysobjects WHERE xtype = 'P'
	AND name = 'PackageVersionGetLatestByPackagePathID'
)
	DROP PROCEDURE PackageVersionGetLatestByPackagePathID
GO
CREATE PROCEDURE PackageVersionGetLatestByPackagePathID
	@PackagePathID	int
AS BEGIN
	SELECT * FROM PackageVersion
	WHERE	PackageVersionID =
	(SELECT	MAX(PackageVersionID) 
		FROM PackageVersion
		WHERE PackagePathID = @PackagePathID
	)
END
GO

PRINT 'Creating procedure to get existing PackageVersions by PackageName'
IF EXISTS(SELECT * FROM sysobjects WHERE xtype = 'P'
	AND name = 'PackageVersionsByPackageName'
)
	DROP PROCEDURE PackageVersionsByPackageName
GO
CREATE PROCEDURE PackageVersionsByPackageName
	@PackageName		nvarchar(64)
AS BEGIN
	SELECT 	pv.Version 
	FROM 	PackageVersion as pv, 
		PackageFamily as pf 
	WHERE 	pv.PackageFamilyID = pf.PackageFamilyID 
	  AND 	pf.PackageName = @PackageName

	RETURN @@ROWCOUNT
END
GO


PRINT 'Creating procedure to clear PackageVersionArchitectures by PackagePath'
IF EXISTS(SELECT * FROM sysobjects WHERE xtype = 'P'
	AND name = 'PackageVersionArchitectureRemoveAllByPackagePath'
)
	DROP PROCEDURE PackageVersionArchitectureRemoveAllByPackagePath
GO
CREATE PROCEDURE PackageVersionArchitectureRemoveAllByPackagePath
	@PackageFullName	nvarchar(256),
	@PackageName		nvarchar(64),
	@Version		nvarchar(32)
AS BEGIN
	DECLARE @PackagePathID int
	DECLARE @PackageFamilyID int
	DECLARE @PackageVersionID int
	DECLARE @PackagePathTypeID int
	
	EXEC @PackagePathID = PackagePathBind @PackageFullName
	EXEC @PackageFamilyID = PackageFamilyBind @PackageName

	SELECT @PackageVersionID = PackageVersionID
	FROM PackageVersion AS v, PackagePath AS p
	WHERE p.PackageFullName = @PackageFullName
	  AND v.PackagePathID = p.PackagePathID
	  AND v.Version = @Version
	
	-- If there is an existing Package with this Version is in the database
	IF @@ROWCOUNT = 1
	BEGIN
		EXEC PackageVersionArchitectureRemoveAllByPackageVersionID @PackageVersionID
	END
	
END
GO


PRINT 'Creating procedure to clear PackageVersionEnvironments by PackagePath'
IF EXISTS(SELECT * FROM sysobjects WHERE xtype = 'P'
	AND name = 'PackageVersionEnvironmentRemoveAllByPackagePath'
)
	DROP PROCEDURE PackageVersionEnvironmentRemoveAllByPackagePath
GO
CREATE PROCEDURE PackageVersionEnvironmentRemoveAllByPackagePath
	@PackageFullName	nvarchar(256),
	@PackageName		nvarchar(64),
	@Version		nvarchar(32)
AS BEGIN
	DECLARE @PackagePathID int
	DECLARE @PackageFamilyID int
	DECLARE @PackageVersionID int

	EXEC @PackagePathID = PackagePathBind @PackageFullName
	EXEC @PackageFamilyID = PackageFamilyBind @PackageName

	SELECT @PackageVersionID = PackageVersionID
	FROM PackageVersion AS v, PackagePath AS p
	WHERE p.PackageFullName = @PackageFullName
	  AND v.PackagePathID = p.PackagePathID
	  AND v.Version = @Version
	
	-- If there is an existing Package with this Version is in the database
	IF @@ROWCOUNT = 1
	BEGIN
		EXEC PackageVersionEnvironmentRemoveAllByPackageVersionID @PackageVersionID
	END
	
END
GO



PRINT 'Creating procedure to clear PackageVersionLocales by PackagePath'
IF EXISTS(SELECT * FROM sysobjects WHERE xtype = 'P'
	AND name = 'PackageVersionLocaleRemoveAllByPackagePath'
)
	DROP PROCEDURE PackageVersionLocaleRemoveAllByPackagePath
GO
CREATE PROCEDURE PackageVersionLocaleRemoveAllByPackagePath
	@PackageFullName	nvarchar(256),
	@PackageName		nvarchar(64),
	@Version		nvarchar(32)
AS BEGIN
	DECLARE @PackagePathID int
	DECLARE @PackageFamilyID int
	DECLARE @PackageVersionID int

	EXEC @PackagePathID = PackagePathBind @PackageFullName
	EXEC @PackageFamilyID = PackageFamilyBind @PackageName

	SELECT @PackageVersionID = PackageVersionID
	FROM PackageVersion AS v, PackagePath AS p
	WHERE p.PackageFullName = @PackageFullName
	  AND v.PackagePathID = p.PackagePathID
	  AND v.Version = @Version
	
	-- If there is an existing Package with this Version is in the database
	IF @@ROWCOUNT = 1
	BEGIN
		EXEC PackageVersionLocaleRemoveAllByPackageVersionID @PackageVersionID
	END
	
END
GO


PRINT 'Creating procedure to add PackageVersionArchitectures by PackagePath'
IF EXISTS(SELECT * FROM sysobjects WHERE xtype = 'P'
	AND name = 'PackageVersionArchitectureAddByPackagePath'
)
	DROP PROCEDURE PackageVersionArchitectureAddByPackagePath
GO
CREATE PROCEDURE PackageVersionArchitectureAddByPackagePath
	@PackageFullName	nvarchar(256),
	@PackageName		nvarchar(64),
	@Version		nvarchar(32),
	@PackageType		nvarchar(128),
	@ArchitectureName	nvarchar(64)
AS BEGIN
	DECLARE @ArchitectureID	int
	DECLARE @PackagePathID int
	DECLARE @PackageFamilyID int
	DECLARE @PackageVersionID int
	DECLARE @PackagePathTypeID int
	DECLARE @ParentPathID int
	
	-- Default PackagePathTypeID to unknown
	Set @PackagePathTypeID = 1

	SELECT @PackagePathTypeID = PackagePathTypeID 
	FROM PackagePathType 
	WHERE Description = @PackageType

	EXEC @ParentPathID = PackagePathAddFolders @PackageFullName

	IF @ParentPathID = 0
		SET @ParentPathID = NULL
		
	EXEC @PackagePathID = PackagePathBind @PackageFullName, @ParentPathID, @PackagePathTypeID

	IF NOT EXISTS(
		SELECT	PackagePathTypeID
		FROM	PackagePath
		WHERE	PackagePathID = @PackagePathID
		  AND	PackagePathTypeID = @PackagePathTypeID
	)
	BEGIN
		-- Update the package path type ID
		UPDATE	PackagePath
		SET	PackagePathTypeID = @PackagePathTypeID
		WHERE	PackagePathID = @PackagePathID
	END

	EXEC @PackageFamilyID = PackageFamilyBind @PackageName
	EXEC @ArchitectureID = ArchitectureBind @ArchitectureName
	
	SELECT @PackageVersionID = PackageVersionID
	FROM PackageVersion AS v, PackagePath AS p
	WHERE p.PackageFullName = @PackageFullName
	  AND v.PackagePathID = p.PackagePathID
	  AND v.Version = @Version

	IF @ArchitectureID IS NOT NULL AND @ArchitectureID <> 0 AND @PackageVersionID IS NOT NULL AND @ArchitectureName NOT LIKE 'lgcy%'
	BEGIN
		EXEC PackageVersionArchitectureAdd @PackageVersionID, @ArchitectureID
	END

END
GO


PRINT 'Creating procedure to add PackageVersionLocales by PackagePath'
IF EXISTS(SELECT * FROM sysobjects WHERE xtype = 'P'
	AND name = 'PackageVersionLocaleAddByPackagePath'
)
	DROP PROCEDURE PackageVersionLocaleAddByPackagePath
GO
CREATE PROCEDURE PackageVersionLocaleAddByPackagePath
	@PackageFullName	nvarchar(256),
	@PackageName		nvarchar(64),
	@Version		nvarchar(32),
	@PackageType		nvarchar(128),
	@LocaleCode		nchar(6)
AS BEGIN
	DECLARE @PackagePathID int
	DECLARE @PackageFamilyID int
	DECLARE @PackageVersionID int
	DECLARE @PackagePathTypeID int
	DECLARE @ParentPathID int
	
	-- Default PackagePathTypeID to unknown
	Set @PackagePathTypeID = 1

	SELECT @PackagePathTypeID = PackagePathTypeID 
	FROM PackagePathType 
	WHERE Description = @PackageType

	EXEC @ParentPathID = PackagePathAddFolders @PackageFullName

	IF @ParentPathID = 0
		SET @ParentPathID = NULL
		
	EXEC @PackagePathID = PackagePathBind @PackageFullName, @ParentPathID, @PackagePathTypeID

	IF NOT EXISTS(
		SELECT	PackagePathTypeID
		FROM	PackagePath
		WHERE	PackagePathID = @PackagePathID
		  AND	PackagePathTypeID = @PackagePathTypeID
	)
	BEGIN
		-- Update the package path type ID
		UPDATE	PackagePath
		SET	PackagePathTypeID = @PackagePathTypeID
		WHERE	PackagePathID = @PackagePathID
	END

	EXEC @PackageFamilyID = PackageFamilyBind @PackageName
	
	SELECT @PackageVersionID = PackageVersionID
	FROM PackageVersion AS v, PackagePath AS p
	WHERE p.PackageFullName = @PackageFullName
	  AND v.PackagePathID = p.PackagePathID
	  AND v.Version = @Version

	IF @LocaleCode IS NOT NULL AND @PackageVersionID IS NOT NULL AND @LocaleCode NOT LIKE 'lgcy%'
	BEGIN
		EXEC PackageVersionLocaleAdd @PackageVersionID, @LocaleCode
	END

END
GO


PRINT 'Creating procedure to add PackageVersionEnvironments by PackagePath'
IF EXISTS(SELECT * FROM sysobjects WHERE xtype = 'P'
	AND name = 'PackageVersionEnvironmentAddByPackagePath'
)
	DROP PROCEDURE PackageVersionEnvironmentAddByPackagePath
GO
CREATE PROCEDURE PackageVersionEnvironmentAddByPackagePath
	@PackageFullName	nvarchar(256),
	@PackageName		nvarchar(64),
	@Version		nvarchar(32),
	@PackageType		nvarchar(128),
	@Environment		nvarchar(128)
AS BEGIN
	DECLARE @PackagePathID int
	DECLARE @PackageFamilyID int
	DECLARE @PackageVersionID int
	DECLARE @PackagePathTypeID int
	DECLARE @ParentPathID int
	
	-- Default PackagePathTypeID to unknown
	Set @PackagePathTypeID = 1

	SELECT @PackagePathTypeID = PackagePathTypeID 
	FROM PackagePathType 
	WHERE Description = @PackageType

	EXEC @ParentPathID = PackagePathAddFolders @PackageFullName

	IF @ParentPathID = 0
		SET @ParentPathID = NULL
		
	EXEC @PackagePathID = PackagePathBind @PackageFullName, @ParentPathID, @PackagePathTypeID

	IF NOT EXISTS(
		SELECT	PackagePathTypeID
		FROM	PackagePath
		WHERE	PackagePathID = @PackagePathID
		  AND	PackagePathTypeID = @PackagePathTypeID
	)
	BEGIN
		-- Update the package path type ID
		UPDATE	PackagePath
		SET	PackagePathTypeID = @PackagePathTypeID
		WHERE	PackagePathID = @PackagePathID
	END

	EXEC @PackageFamilyID = PackageFamilyBind @PackageName
	
	SELECT @PackageVersionID = PackageVersionID
	FROM PackageVersion AS v, PackagePath AS p
	WHERE p.PackageFullName = @PackageFullName
	  AND v.PackagePathID = p.PackagePathID
	  AND v.Version = @Version

	IF @Environment IS NOT NULL AND @PackageVersionID IS NOT NULL
	BEGIN
		EXEC PackageVersionEnvironmentAdd @PackageVersionID, @Environment
	END

END
GO


PRINT 'Creating procedure to create/update folder on PackagePath'
IF EXISTS(SELECT * FROM sysobjects WHERE xtype = 'P'
	AND [name] = 'PackagePathAddFolders'
)
	DROP PROCEDURE PackagePathAddFolders
GO
CREATE PROCEDURE PackagePathAddFolders
	@PackageFullName NVARCHAR(256)
AS BEGIN

	DECLARE @Position as int
	DECLARE @SubPath as nvarchar(256)
	DECLARE @InitialPosition as int
	DECLARE @ParentPathID int

	Set @ParentPathID = NULL 
	Set @InitialPosition = 0
	Set @SubPath = NULL
	Set @Position = CHARINDEX('/', @PackageFullName, @InitialPosition)

	WHILE (@Position <> 0)
	BEGIN
		-- Increment the InitialPosition to find
		-- next /
		Set @InitialPosition = @Position + 1
		Set @SubPath = SUBSTRING(@PackageFullName, 0, @Position)

		-- Look for the next /
		set @Position = CHARINDEX('/', @PackageFullName, @InitialPosition)

		-- Need to omit the path after the last / as 
		-- this is not a folder
		IF (@Position <> 0)
		BEGIN
			EXEC @ParentPathID = PackagePathBind @SubPath, @ParentPathID, 7
			
			-- Update the Warehouse's MediaContainPackagePath
			-- with this folder
			IF NOT EXISTS( SELECT * FROM MediaContainsPackagePath
					WHERE MediaID = 1 
					AND PackagePathID = @ParentPathID
			)
			BEGIN
				INSERT MediaContainsPackagePath (MediaID, PackagePathID)
				VALUES (1, @ParentPathID)
			END
			
		END
	END

	IF @ParentPathID is NULL
		Set @ParentPathID = 0
	
	RETURN @ParentPathID

END
GO

PRINT 'Creating procedure to delete folders on MediaContainsPackagePath'
IF EXISTS(SELECT * FROM sysobjects WHERE xtype = 'P'
	AND [name] = 'MediaContainsPackagePathRemoveByPackageFullName'
)
	DROP PROCEDURE MediaContainsPackagePathRemoveByPackageFullName
GO
CREATE PROCEDURE MediaContainsPackagePathRemoveByPackageFullName
	@PackageFullName NVARCHAR(256)
AS BEGIN

	DECLARE @Position int
	DECLARE @Path nvarchar(256)
	DECLARE @InitialPosition int
	DECLARE @PackagePathID int

	SET @Path = @PackageFullName
	
	DELETE MediaContainsPackagePath
	WHERE MediaID = 1 
	   AND PackagePathID IN (
	   	SELECT PackagePathID 
		FROM PackagePath
		WHERE PackageFullName = @Path
	)

	-- Do a reverse search for /
	Set @InitialPosition = LEN(@Path)

	WHILE (@InitialPosition > 0)
	BEGIN
		Set @Position = CHARINDEX('/', @Path, @InitialPosition)

		-- Found /
		IF (@Position <> 0)
		BEGIN
			-- Substring from start to Position, basically
			-- remove characters after /
			Set @Path = SUBSTRING(@Path, 0, @Position)

			-- Get ID from PackageFullName
			SELECT @PackagePathID = PackagePathID
			FROM PackagePath
			WHERE PackageFullName = @Path

			-- Get all children packages/folder
			DECLARE ppCursor CURSOR FOR
				SELECT PackagePathID 
				FROM PackagePath
				WHERE ParentPathID = @PackagePathID

			DECLARE @cPackagePathID int
			DECLARE @EmptyFolder int

			SET @EmptyFolder = 1
			
			OPEN ppCursor
			FETCH NEXT FROM ppCursor INTO @cPackagePathID
			WHILE @@FETCH_STATUS = 0
			BEGIN
				
				-- If the child package/folder still 
				-- exists, the folder is not empty
				IF EXISTS(SELECT *
					FROM MediaContainsPackagePath
					WHERE PackagePathID = @cPackagePathID
				)
				BEGIN
					SET @EmptyFolder = 0
					BREAK
				END

				-- Fetch next
				FETCH NEXT FROM ppCursor INTO @cPackagePathID
			END

			CLOSE ppCursor
			DEALLOCATE ppCursor

			-- If folder is empty, delete it from
			-- MediaContainsPackagePath
			IF @EmptyFolder = 1
			BEGIN
				DELETE MediaContainsPackagePath
				WHERE MediaID = 1 
				   AND PackagePathID = @PackagePathID
			END
			
		END

		-- Decrement InitialPosition. 
		-- Remember, we are doing reverse search
		SET @InitialPosition = @InitialPosition - 1

	END
END
GO


PRINT 'Creating procedure determine whether a package is used in policy'
IF EXISTS(SELECT * FROM sysobjects WHERE xtype = 'P'
        AND [name] = 'PackageExistsInPolicy'
)
        DROP PROCEDURE PackageExistsInPolicy
GO
CREATE PROCEDURE PackageExistsInPolicy
        @PackageFullName NVARCHAR(256)
AS BEGIN
        SELECT  DISTINCT
                pp.packageFullName,
                p.GUID,
                p.DisplayName,
                d.DN
        FROM
                PackagePath pp,
                PackageAllocation pa,
                Policy p,
                Domain d
        WHERE   pa.PolicyGUID = p.GUID
          AND   pa.PackagePathID = pp.PackagePathID
          AND   pp.PackageFullName = @PackageFullName
          AND   p.DomainID = d.OrganizationID
END
GO
/*
 * $Id: Inventory.sql 93201 2009-08-05 04:55:35Z pca $
 *
 * Miscellaneous inventory related stored procedures.
 *
 * Protected by US patent 6,006,034; patents pending.
 * Copyright 2000-2003 ManageSoft Corporation. All rights reserved.
 * Reproduction, adaptation, or translation without prior permission
 * is prohibited.
 */

-- USE ManageSoft
GO

IF EXISTS (
	SELECT * FROM dbo.sysobjects
	WHERE [name] = 'HardwareValueGetAllByComputerID' AND xtype = 'P'
)
	DROP PROCEDURE HardwareValueGetAllByComputerID
GO
CREATE PROCEDURE HardwareValueGetAllByComputerID
	@ComputerID int
AS
	SELECT	HardwareValue.HardwareObjectID,
		HardwareValue.HardwarePropertyID,
		HardwareValue.Value
	FROM HardwareValue 
	INNER JOIN HardwareObject
	ON HardwareValue.HardwareObjectID = HardwareObject.HardwareObjectID
	WHERE HardwareObject.ComputerID = @ComputerID
	RETURN @@ROWCOUNT
GO

IF EXISTS (
	SELECT * FROM dbo.sysobjects
	WHERE [name] = 'SoftwareValueGetAllByComputerIDUserID' AND xtype = 'P'
)
	DROP PROCEDURE SoftwareValueGetAllByComputerIDUserID
GO
CREATE PROCEDURE SoftwareValueGetAllByComputerIDUserID
	@ComputerID int,
	@UserID int
AS
	SELECT	SoftwareValue.SoftwareOccurrenceID,
		SoftwareValue.SoftwarePropertyID,
		SoftwareValue.Value
	FROM SoftwareValue 
	INNER JOIN SoftwareOccurrence
	ON SoftwareValue.SoftwareOccurrenceID = SoftwareOccurrence.SoftwareOccurrenceID
	WHERE SoftwareOccurrence.ComputerID = @ComputerID
	  AND SoftwareOccurrence.UserID = @UserID
	RETURN @@ROWCOUNT
GO
/*
 * $Id: Distribution.sql 89700 2008-10-08 02:01:37Z tnguyen $
 *
 * Procedures to use in updating DistributionServer table rows
 *
 * Protected by US patent 6,006,034; patents pending.
 * Copyright 2000-2003 ManageSoft Corporation. All rights reserved.
 * Reproduction, adaptation, or translation without prior permission
 * is prohibited.
 */
-- USE ManageSoft
GO

PRINT 'Creating procedure to update a distribution server name'
IF EXISTS(SELECT * FROM sysobjects WHERE xtype = 'P'
        AND [name] = 'DistributionServerUpdateServerNameByServerUID'
)
        DROP PROCEDURE DistributionServerUpdateServerNameByServerUID
GO
CREATE PROCEDURE DistributionServerUpdateServerNameByServerUID
	@ServerUID	binary(16),
	@ServerName	nvarchar(64)
AS
	UPDATE DistributionServer
	SET ServerName = @ServerName
	WHERE ServerUID = @ServerUID
GO

PRINT 'Creating procedure to update a distribution server DNS name'
IF EXISTS(SELECT * FROM sysobjects WHERE xtype = 'P'
        AND [name] = 'DistributionServerUpdateDNSNameByServerUID'
)
        DROP PROCEDURE DistributionServerUpdateDNSNameByServerUID
GO
CREATE PROCEDURE DistributionServerUpdateDNSNameByServerUID
	@ServerUID	binary(16),
	@DNSName	nvarchar(128)
AS
	UPDATE DistributionServer
	SET DNSName = @DNSName
	WHERE ServerUID = @ServerUID
GO

PRINT 'Creating procedure to update a distribution server parent'
IF EXISTS(SELECT * FROM sysobjects WHERE xtype = 'P'
        AND [name] = 'DistributionServerUpdatePrimaryParentUIDByServerUID'
)
        DROP PROCEDURE DistributionServerUpdatePrimaryParentUIDByServerUID
GO
CREATE PROCEDURE DistributionServerUpdatePrimaryParentUIDByServerUID
	@ServerUID		binary(16),
	@PrimaryParentUID	binary(16)
AS
	UPDATE DistributionServer
	SET PrimaryParentUID = @PrimaryParentUID
	WHERE ServerUID = @ServerUID
GO

PRINT 'Creating procedure to create a distribution group'
IF EXISTS(SELECT * FROM sysobjects WHERE xtype = 'P'
	AND name = 'DistributionGroupCreate'
)
	DROP PROCEDURE DistributionGroupCreate
GO
CREATE PROCEDURE DistributionGroupCreate
	@p_GroupName 	nvarchar(128),
	@p_GroupGuid 	binary(16)
AS
	BEGIN TRANSACTION		
	IF NOT EXISTS(
		SELECT * FROM DistributionGroup
			WHERE GroupName = @p_GroupName
	)
	BEGIN
		INSERT INTO DistributionGroup (GroupUID, GroupName)
			VALUES (@p_GroupGuid, @p_GroupName)
		INSERT INTO DistributionGroupMember (GroupUID, MemberID, MemberType)
			SELECT	@p_GroupGuid,
				ServerUID,
				11
			FROM DistributionServer
				WHERE ServerType = 0
	END
	COMMIT TRANSACTION
GO

PRINT 'Creating procedure to query all distribution servers by type'
IF EXISTS(SELECT * FROM sysobjects WHERE xtype = 'P'
	AND name = 'DistributionServerGetByType'
)
	DROP PROCEDURE DistributionServerGetByType
GO
CREATE PROCEDURE DistributionServerGetByType
	@serverType	int
AS
	SELECT	*
	FROM	DistributionServer
	WHERE	ServerType = @serverType
GO

PRINT 'Creating procedure to query all distribution groups and members'
IF EXISTS(SELECT * FROM sysobjects WHERE xtype = 'P'
	AND name = 'DistributionGroupGetAllMembers'
)
	DROP PROCEDURE DistributionGroupGetAllMembers
GO
CREATE PROCEDURE DistributionGroupGetAllMembers
AS
	SELECT	dgm.GroupUID,
		MemberID,
		(
			SELECT	dg.GroupName
			FROM	DistributionGroup dg
			WHERE	dg.GroupUID = dgm.MemberID 
			  AND	dgm.MemberType = 10
		) AS GroupName,
		(
			SELECT	ServerName
			FROM	DistributionServer ds
			WHERE	ds.ServerUID = dgm.MemberID
			  AND	dgm.MemberType = 11
		) AS ServerName
	FROM	DistributionGroupMember dgm
	ORDER BY GroupName, ServerName
GO

PRINT 'Creating procedure to query all servers that a particular package has been distributed to'
IF EXISTS(SELECT * FROM sysobjects WHERE xtype = 'P'
	AND name = 'GetDistributionServerUIDsForPackageFullName'
)
	DROP PROCEDURE GetDistributionServerUIDsForPackageFullName
GO
CREATE PROCEDURE GetDistributionServerUIDsForPackageFullName
	@PackageFullName nvarchar(256)
AS
	SELECT	dp.ServerUID 
	FROM	DistributedPackage AS dp, 	
		PackageVersion AS pv, 	
		PackagePath AS pp 
	WHERE	dp.RequestedVersionID = pv.PackageVersionID   
	AND	pv.PackagePathID = pp.PackagePathID   
	AND	pp.PackageFullName = @PackageFullName

GO

/*
 * $Id: discovery.sql 98870 2010-12-17 01:47:27Z rlowery $
 *
 * Description:
 *
 * SQL Script to add ManageSoft discovery stored procedures
 * to Microsoft SQL Server.
 *
 * The steps performed by this script are:
 * 1. Add AddNetworkDevice procedure
 * 2. Add UpdateNetworkDevices procedure
 * 3. Add ClearNetworkDevices procedure
 *
 * Protected by US patent 6,006,034; patents pending.
 * Copyright 2000-2002 ManageSoft Corporation. All rights reserved.
 * Reproduction, adaptation, or translation without prior permission
 * is prohibited.
 *
 * Copyright 1995-2002 ManageSoft Corporation Ltd ABN 40 052 412 156. All rights reserved.
 */

-- Use ManageSoft database
-- USE ManageSoft
GO

-- Create AddNetworkDevice stored procedure
PRINT 'Creating procedure to add or update a network discovery device'
IF EXISTS(SELECT * FROM sysobjects WHERE xtype = 'P'
	AND name = 'AddNetworkDevice'
)
	DROP PROCEDURE AddNetworkDevice
GO
CREATE PROCEDURE AddNetworkDevice
	@AllowDuplicates BIT = 1,
	@ComputerID INT = NULL,
	@DeviceName NVARCHAR(64) = NULL,
	@DNSFullName NVARCHAR(256) = NULL,
	@NTDomainName NVARCHAR(256) = NULL,
	@IPAddress VARCHAR(64) = NULL,
	@IPSubnet VARCHAR(64) = NULL,
	@IPSubnetMask VARCHAR(64) = NULL,
	@PhysicalAddress VARCHAR(64) = NULL,
	@DeviceRole INT = NULL,
	@OperatingSystem NVARCHAR(128) = NULL,
	@OperatingSystemID INT = NULL,
	@IsManaged INT = NULL,
	@Description NVARCHAR(256) = NULL,
	@SystemDescription NVARCHAR(256) = NULL,
	@SystemLocation NVARCHAR(256) = NULL,
	@SystemContact NVARCHAR(256) = NULL,
	@LastDataSourceName NVARCHAR(128) = NULL,
	@LastDataSourceType NVARCHAR(32) = NULL,
	@DiscoveringServerUID BINARY(16) = NULL,
	@DiscoveringServerCanAdminister INT = 2, --unknown

	@OpenPortsTCP		varchar(512) = NULL,
	@OpenPortsUDP		varchar(512) = NULL,
	@ScannedOperatingSystem	nvarchar(512) = NULL,

	@ScannedOsType		nvarchar(512) = NULL,
	@ScannedOsVendor	nvarchar(512) = NULL,
	@ScannedOsFamily	nvarchar(512) = NULL,
	@ScannedOsGen		nvarchar(512) = NULL,
	@ScannedMacAddress	varchar(64) = NULL,
	@ScannedMacVendor	nvarchar(512) = NULL,

	@SNMP_snmpCommunityString nvarchar(256) = NULL,
	@SNMP_sysDescr		nvarchar(256) = NULL,
	@SNMP_sysObjectID	nvarchar(256) = NULL,
	@SNMP_sysObjectIDSymbolic nvarchar(256) = NULL,
	@SNMP_sysUpTime		bigint = NULL,
	@SNMP_sysContact	nvarchar(256) = NULL,
	@SNMP_sysName		nvarchar(256) = NULL,
	@SNMP_sysLocation	nvarchar(256) = NULL,
	@SNMP_sysServices	int = NULL,
	@SNMP_ipForwarding	int = NULL,

	@AccountID INT = NULL,

	@AMT_Secure INT = NULL,
	@AMT_Description NVARCHAR(256) = NULL,

	@Virtualization_Protocol VARCHAR(16) = NULL,
	@Virtualization_Port INT = NULL,
	@Virtualization_APIType VARCHAR(32) = NULL,
	@Virtualization_APIVersion VARCHAR(16) = NULL,
	@Virtualization_NameID INT = NULL,
	@Virtualization_Version VARCHAR(16) = NULL,
	@IsSQL INT = NULL,
	@SQLDiscoveredBy NVARCHAR(128) = NULL,
	@SQLPorts NVARCHAR(128) = NULL,

	@DeviceID_OUT INT = NULL OUTPUT
AS
BEGIN
	-- We need at least one of DeviceName, DNSFullName, SNMP_sysName or PhysicalAddress
	IF (@DeviceName IS NULL 
		AND @DNSFullName IS NULL 
		AND @SNMP_sysName IS NULL 
		AND @PhysicalAddress IS NULL
		AND (@IPAddress IS NULL
			OR EXISTS (
			SELECT * FROM NetworkDevice AS nd
			LEFT OUTER JOIN NetworkDeviceSNMPInfo AS ndsi
			ON ndsi.DeviceID = nd.DeviceID
			WHERE IPAddress = @IPAddress 
			AND (
			DeviceName IS NOT NULL 
			OR DNSFullName IS NOT NULL 
			OR ndsi.SNMP_sysName IS NOT NULL 
			OR PhysicalAddress IS NOT NULL
			)))
		)
		RETURN

	-- Make sure we overwrite IP-only discovery records with more complete data		
	IF (@AllowDuplicates = 1
		AND EXISTS (
			SELECT * FROM NetworkDevice AS nd
			LEFT OUTER JOIN NetworkDeviceSNMPInfo AS ndsi
			ON ndsi.DeviceID = nd.DeviceID
			WHERE IPAddress = @IPAddress 
			AND DeviceName IS NULL 
			AND DNSFullName IS NULL 
			AND ndsi.SNMP_sysName IS NULL 
			AND PhysicalAddress IS NULL))
		SET @AllowDuplicates = 0

	PRINT 'AddNetworkDevice '
		+ ISNULL(@DeviceName, '<null>')
		+ ',' + ISNULL(@IPAddress, '<null>')
		+ ',' + ISNULL(@PhysicalAddress, '<null>')
		+ ',' + ISNULL(@DNSFullName, '<null>')
		+ ',' + ISNULL(@NTDomainName, '<null>')

	-- Populate the operating system name and ID: Trust the ID more!
	IF (@OperatingSystemID IS NOT NULL)
		SELECT @OperatingSystem = OperatingSystemName
			FROM OperatingSystem
			WHERE OperatingSystemID = @OperatingSystemID
	ELSE IF (@OperatingSystem IS NOT NULL)
		SELECT @OperatingSystemID = OperatingSystemID
			FROM OperatingSystem
			WHERE OperatingSystemName = @OperatingSystem

	-- It is possible to have separate rows representing the same
	-- device, for example, if an IP and no name was added and a
	-- name with no IP was added.  If later this procedure gets
	-- called with both name and IP then we have to merge the rows
	-- together.  We do this in order of LastUpdate so that the
	-- merged row is the most recent information.  Note that
	-- because we have 3 keys used to lookup a device we may have
	-- to merge as many as 3 rows into 1.

	-- Variables for merge
	DECLARE @PrimaryDeviceID	INT
	DECLARE @FirstDeviceID		INT
	DECLARE @FirstDeviceDuplicateID INT
	DECLARE @OldDeviceID		INT
	DECLARE @OldDuplicateID		INT
	DECLARE @OldComputerID		INT
	DECLARE @OldDeviceName		NVARCHAR(64)
	DECLARE @OldDNSFullName		NVARCHAR(256)
	DECLARE @OldNTDomainName	NVARCHAR(256)
	DECLARE @OldIPAddress		VARCHAR(64)
	DECLARE @OldIPSubnet		VARCHAR(64)
	DECLARE @OldIPSubnetMask	VARCHAR(64)
	DECLARE @OldPhysicalAddress	VARCHAR(64)
	DECLARE @OldDeviceRole		INT
	DECLARE @OldOperatingSystem	NVARCHAR(128)
	DECLARE @OldOperatingSystemID	INT
	DECLARE @OldIsManaged		INT
	DECLARE @OldDescription		NVARCHAR(256)
	DECLARE @OldSystemDescription	NVARCHAR(256)
	DECLARE @OldSystemLocation	NVARCHAR(256)
	DECLARE @OldSystemContact	NVARCHAR(256)
	DECLARE @OldFirstDiscovered	DATETIME
	DECLARE @OldLastUpdate		DATETIME
	DECLARE @OldLastDataSourceName	NVARCHAR(128)
	DECLARE @OldLastDataSourceType	NVARCHAR(32)
	DECLARE @FirstDiscovered	DATETIME
	DECLARE @InvOperatingSystemID	INT
	DECLARE @IsBetter		BIT	-- Result from OperatingSystem category check

	DECLARE @OldOpenPortsTCP			varchar(512)
	DECLARE @OldOpenPortsUDP			varchar(512)
	DECLARE @OldScannedOperatingSystem	nvarchar(512)

	DECLARE @OldScannedOsType		nvarchar(512)
	DECLARE @OldScannedOsVendor		nvarchar(512)
	DECLARE @OldScannedOsFamily		nvarchar(512)
	DECLARE @OldScannedOsGen		nvarchar(512)
	DECLARE @OldScannedMacAddress	varchar(64)
	DECLARE @OldScannedMacVendor	nvarchar(512)

	DECLARE @OldSNMP_snmpCommunityString nvarchar(256)
	DECLARE @OldSNMP_sysDescr			nvarchar(256)
	DECLARE @OldSNMP_sysObjectID		nvarchar(256)
	DECLARE @OldSNMP_sysObjectIDSymbolic nvarchar(256)
	DECLARE @OldSNMP_sysUpTime			bigint
	DECLARE @OldSNMP_sysContact			nvarchar(256)
	DECLARE @OldSNMP_sysName			nvarchar(256)
	DECLARE @OldSNMP_sysLocation		nvarchar(256)
	DECLARE @OldSNMP_sysServices		int
	DECLARE @OldSNMP_ipForwarding		int

	DECLARE @OldAMT_Secure		int
	DECLARE @OldAMT_Description		nvarchar(256)

	DECLARE @OldVirtualization_Protocol VARCHAR(16)
	DECLARE @OldVirtualization_Port INT
	DECLARE @OldVirtualization_APIType VARCHAR(32)
	DECLARE @OldVirtualization_APIVersion VARCHAR(16)
	DECLARE @OldVirtualization_NameID INT
	DECLARE @OldVirtualization_Version VARCHAR(16)

	-- Begin transaction
	BEGIN TRANSACTION

	-- Open cursor for merging duplicates
	IF @AllowDuplicates = 1
	BEGIN
		-- Look for duplicate primary device
		SELECT	@PrimaryDeviceID = DeviceID
		FROM	NetworkDevice
		WHERE	DuplicateID IS NULL
			AND (
				-- matching on PhysicalAddress REGARDLESS
				PhysicalAddress = @PhysicalAddress

				-- matching on DeviceName, if there are no contradictions
				OR (	DeviceName = @DeviceName
					AND (	--no contradiction on DNSFullName
						@DNSFullName IS NULL
						OR DNSFullName IS NULL
						OR @DNSFullName = DNSFullName
					)
					AND (	--no contradiction on NTDomainName
						@NTDomainName IS NULL
						OR NTDomainName IS NULL
						OR @NTDomainName = NTDomainName
					)
				)

				-- matching on DNSFullName, if there are no contradictions
				OR (	DNSFullName = @DNSFullName
					AND (	--no contradiction on DeviceName
						@DeviceName IS NULL
						OR DeviceName IS NULL
						OR @DeviceName = DeviceName
					)
					AND (	--no contradiction on NTDomainName
						@NTDomainName IS NULL
						OR NTDomainName IS NULL
						OR @NTDomainName = NTDomainName
					)
				)
			)

		-- Exact match on all identifying values
		DECLARE DuplicateCursor CURSOR FOR
		SELECT	nd.DeviceID,
			nd.DuplicateID,
			nd.ComputerID,
			nd.DeviceName,
			nd.DNSFullName,
			nd.NTDomainName,
			nd.IPAddress,
			nd.IPSubnet,
			nd.IPSubnetMask,
			nd.PhysicalAddress,
			nd.DeviceRole,
			nd.OperatingSystem,
			nd.OperatingSystemID,
			nd.IsManaged,
			nd.Description,
			nd.SystemDescription,
			nd.SystemLocation,
			nd.SystemContact,
			nd.FirstDiscovered,
			nd.LastUpdate,
			nd.LastDataSourceName,
			nd.LastDataSourceType,

			nd.OpenPortsTCP,
			nd.OpenPortsUDP,
			nd.ScannedOperatingSystem,

			nd.ScannedOsType,
			nd.ScannedOsVendor,
			nd.ScannedOsFamily,
			nd.ScannedOsGen,
			nd.ScannedMacAddress,
			nd.ScannedMacVendor,

			ndsi.SNMP_snmpCommunityString,
			ndsi.SNMP_sysDescr,
			ndsi.SNMP_sysObjectID,
			ndsi.SNMP_sysObjectIDSymbolic,
			ndsi.SNMP_sysUpTime,
			ndsi.SNMP_sysContact,
			ndsi.SNMP_sysName,
			ndsi.SNMP_sysLocation,
			ndsi.SNMP_sysServices,
			ndsi.SNMP_ipForwarding,

			ndai.Secure AS AMT_Secure,
			ndai.Description AS AMT_Description,

			ndvi.Protocol AS Virtualization_Protocol,
			ndvi.Port AS Virtualization_Port,
			ndvi.APIType AS Virtualization_APIType,
			ndvi.APIVersion AS Virtualization_APIVersion,
			ndvi.ProductNameID AS Virtualization_NameID,
			ndvi.ProductVersion AS Virtualization_Version

		FROM	NetworkDevice AS nd
		LEFT OUTER JOIN	NetworkDeviceSNMPInfo AS ndsi
			ON ndsi.DeviceID = nd.DeviceID
		LEFT OUTER JOIN	NetworkDeviceAMTInfo AS ndai
			ON ndai.DeviceID = nd.DeviceID
		LEFT OUTER JOIN	NetworkDeviceVirtualizationInfo AS ndvi
			ON ndvi.DeviceID = nd.DeviceID
		WHERE	(nd.PhysicalAddress IS NULL OR nd.PhysicalAddress = @PhysicalAddress)
			AND (nd.DeviceName IS NULL OR nd.DeviceName = @DeviceName)
			AND (nd.DNSFullName IS NULL OR nd.DNSFullName = @DNSFullName)
			AND (nd.PhysicalAddress IS NOT NULL OR nd.DeviceName IS NOT NULL OR nd.DNSFullName IS NOT NULL)
		ORDER BY nd.LastUpdate DESC
	END
	ELSE
	BEGIN
		-- Match up on at least one identifying value
		DECLARE DuplicateCursor CURSOR FOR
		SELECT	nd.DeviceID,
			nd.DuplicateID,
			nd.ComputerID,
			nd.DeviceName,
			nd.DNSFullName,
			nd.NTDomainName,
			nd.IPAddress,
			nd.IPSubnet,
			nd.IPSubnetMask,
			nd.PhysicalAddress,
			nd.DeviceRole,
			nd.OperatingSystem,
			nd.OperatingSystemID,
			nd.IsManaged,
			nd.Description,
			nd.SystemDescription,
			nd.SystemLocation,
			nd.SystemContact,
			nd.FirstDiscovered,
			nd.LastUpdate,
			nd.LastDataSourceName,
			nd.LastDataSourceType,

			nd.OpenPortsTCP,
			nd.OpenPortsUDP,
			nd.ScannedOperatingSystem,

			nd.ScannedOsType,
			nd.ScannedOsVendor,
			nd.ScannedOsFamily,
			nd.ScannedOsGen,
			nd.ScannedMacAddress,
			nd.ScannedMacVendor,

			ndsi.SNMP_snmpCommunityString,
			ndsi.SNMP_sysDescr,
			ndsi.SNMP_sysObjectID,
			ndsi.SNMP_sysObjectIDSymbolic,
			ndsi.SNMP_sysUpTime,
			ndsi.SNMP_sysContact,
			ndsi.SNMP_sysName,
			ndsi.SNMP_sysLocation,
			ndsi.SNMP_sysServices,
			ndsi.SNMP_ipForwarding,

			ndai.Secure AS AMT_Secure,
			ndai.Description AS AMT_Description,

			ndvi.Protocol AS Virtualization_Protocol,
			ndvi.Port AS Virtualization_Port,
			ndvi.APIType AS Virtualization_APIType,
			ndvi.APIVersion AS Virtualization_APIVersion,
			ndvi.ProductNameID AS Virtualization_NameID,
			ndvi.ProductVersion AS Virtualization_Version

		FROM	NetworkDevice AS nd
		LEFT OUTER JOIN	NetworkDeviceSNMPInfo AS ndsi
			ON ndsi.DeviceID = nd.DeviceID
		LEFT OUTER JOIN	NetworkDeviceAMTInfo AS ndai
			ON ndai.DeviceID = nd.DeviceID
		LEFT OUTER JOIN	NetworkDeviceVirtualizationInfo AS ndvi
			ON ndvi.DeviceID = nd.DeviceID

		-- Note: should all this logic be changed, please make sure to update NetworkDeviceFindDuplicateToMergeWith further down
		WHERE	nd.DuplicateID IS NULL
			AND (
				-- matching on PhysicalAddress REGARDLESS
				nd.PhysicalAddress = @PhysicalAddress

				-- matching on SNMP_sysName, if there are no contradictions
				OR (	ndsi.SNMP_sysName = @SNMP_sysName
					AND (	-- no contradiction on DeviceName
						@DeviceName IS NULL
						OR nd.DeviceName IS NULL
						OR @DeviceName = nd.DeviceName
					)
					AND (	-- no contradiction on DNSFullName
						@DNSFullName IS NULL
						OR nd.DNSFullName IS NULL
						OR @DNSFullName = nd.DNSFullName
					)
					AND (	-- no contradiction on NTDomainName
						@NTDomainName IS NULL
						OR nd.NTDomainName IS NULL
						OR @NTDomainName = nd.NTDomainName
					)
				)

				-- matching on DeviceName, if there are no contradictions
				OR (	nd.DeviceName = @DeviceName
					AND (	-- no contradiction on DNSFullName
						@DNSFullName IS NULL
						OR nd.DNSFullName IS NULL
						OR @DNSFullName = nd.DNSFullName
					)
					AND (	-- no contradiction on NTDomainName
						@NTDomainName IS NULL
						OR nd.NTDomainName IS NULL
						OR @NTDomainName = nd.NTDomainName
					)
				)

				-- matching on DNSFullName, if there are no contradictions
				OR (	nd.DNSFullName = @DNSFullName
					AND (	-- no contradiction on DeviceName
						@DeviceName IS NULL
						OR nd.DeviceName IS NULL
						OR @DeviceName = nd.DeviceName
					)
					AND (	-- no contradiction on NTDomainName
						@NTDomainName IS NULL
						OR nd.NTDomainName IS NULL
						OR @NTDomainName = nd.NTDomainName
					)
				)
				
				OR (	nd.DeviceName IS NULL 
					AND nd.DNSFullName IS NULL 
					AND ndsi.SNMP_sysName IS NULL 
					AND nd.PhysicalAddress IS NULL
					AND nd.IPAddress = @IPAddress
					AND NOT EXISTS (
						SELECT * FROM NetworkDevice nd2
						LEFT OUTER JOIN	NetworkDeviceSNMPInfo AS ndsi2
							ON ndsi2.DeviceID = nd2.DeviceID
						WHERE nd2.PhysicalAddress = @PhysicalAddress
						   OR ndsi2.SNMP_sysName = @SNMP_sysName
						   OR nd2.DNSFullName = @DNSFullName
						   OR nd2.DeviceName = @DeviceName
					)
				)
			)

		ORDER BY nd.LastUpdate DESC
	END

	OPEN DuplicateCursor
	FETCH NEXT FROM DuplicateCursor
	INTO	@OldDeviceID,
		@OldDuplicateID,
		@OldComputerID,
		@OldDeviceName,
		@OldDNSFullName,
		@OldNTDomainName,
		@OldIPAddress,
		@OldIPSubnet,
		@OldIPSubnetMask,
		@OldPhysicalAddress,
		@OldDeviceRole,
		@OldOperatingSystem,
		@OldOperatingSystemID,
		@OldIsManaged,
		@OldDescription,
		@OldSystemDescription,
		@OldSystemLocation,
		@OldSystemContact,
		@OldFirstDiscovered,
		@OldLastUpdate,
		@OldLastDataSourceName,
		@OldLastDataSourceType,

		@OldOpenPortsTCP,
		@OldOpenPortsUDP,
		@OldScannedOperatingSystem,

		@OldScannedOsType,
		@OldScannedOsVendor,
		@OldScannedOsFamily,
		@OldScannedOsGen,
		@OldScannedMacAddress,
		@OldScannedMacVendor,

		@OldSNMP_snmpCommunityString,
		@OldSNMP_sysDescr,
		@OldSNMP_sysObjectID,
		@OldSNMP_sysObjectIDSymbolic,
		@OldSNMP_sysUpTime,
		@OldSNMP_sysContact,
		@OldSNMP_sysName,
		@OldSNMP_sysLocation,
		@OldSNMP_sysServices,
		@OldSNMP_ipForwarding,

		@OldAMT_Secure,
		@OldAMT_Description,

		@OldVirtualization_Protocol,
		@OldVirtualization_Port,
		@OldVirtualization_APIType,
		@OldVirtualization_APIVersion,
		@OldVirtualization_NameID,
		@OldVirtualization_Version


	IF @@FETCH_STATUS = 0
	BEGIN
		SET @FirstDeviceID = @OldDeviceID
		SET @FirstDeviceDuplicateID = @OldDuplicateID
		SET @FirstDiscovered = GETDATE()

		-- Merge information from all rows that look like duplicates
		WHILE 1 = 1
		BEGIN
			-- Overwrite NULLs with information from matching rows
			SET @ComputerID = ISNULL(
				@ComputerID, @OldComputerID
			)
			SET @DeviceName = ISNULL(
				@DeviceName, @OldDeviceName
			)
			SET @DNSFullName = ISNULL(
				@DNSFullName, @OldDNSFullName
			)
			SET @NTDomainName = ISNULL(
				@NTDomainName, @OldNTDomainName
			)
			SET @IPAddress = ISNULL(
				@IPAddress, @OldIPAddress
			)
			SET @IPSubnet = ISNULL(
				@IPSubnet, @OldIPSubnet
			)
			SET @IPSubnetMask = ISNULL(
				@IPSubnetMask, @OldIPSubnetMask
			)
			SET @PhysicalAddress = ISNULL(
				@PhysicalAddress, @OldPhysicalAddress
			)
			SET @DeviceRole = ISNULL(
				@DeviceRole, @OldDeviceRole
			)

			-- If OldOperatingSystemID is better/more refined, use it instead
			SET @IsBetter = CASE WHEN (@OperatingSystemID IS NULL
						OR  @OperatingSystemID <= 1)
					THEN 1	-- Anything's better than NULL/unknown/other
					ELSE 0
					END
			IF @IsBetter = 0	--  Old may be better:
				-- If OldOperatingSystem looks ok, is it really better?
				EXEC @IsBetter = OperatingSystemCategoryTest
							@OperatingSystemID,
							@OldOperatingSystemID
			IF @IsBetter <> 0	-- Old definitely *is* better
			BEGIN
				SET @OperatingSystemID = @OldOperatingSystemID
				SELECT @OperatingSystem = OperatingSystemName
					FROM OperatingSystem
					WHERE OperatingSystemID = @OperatingSystemID
			END

			SET @IsManaged = ISNULL(
				@IsManaged, @OldIsManaged
			)
			SET @Description = ISNULL(
				@Description, @OldDescription
			)
			SET @SystemDescription = ISNULL(
				@SystemDescription, @OldSystemDescription
			)
			SET @SystemLocation = ISNULL(
				@SystemLocation, @OldSystemLocation
			)
			SET @SystemContact = ISNULL(
				@SystemContact, @OldSystemContact
			)
			IF (@OldFirstDiscovered < @FirstDiscovered)
				SET @FirstDiscovered = @OldFirstDiscovered
			SET @LastDataSourceName = ISNULL(
				@LastDataSourceName, @OldLastDataSourceName
			)
			SET @LastDataSourceType = ISNULL(
				@LastDataSourceType, @OldLastDataSourceType
			)

			SET @OpenPortsTCP = ISNULL(
				@OpenPortsTCP, @OldOpenPortsTCP
			)
			SET @OpenPortsUDP = ISNULL(
				@OpenPortsUDP, @OldOpenPortsUDP
			)
			SET @ScannedOperatingSystem = ISNULL(
				@ScannedOperatingSystem, @OldScannedOperatingSystem
			)

			SET @ScannedOsType = ISNULL(
				@ScannedOsType, @OldScannedOsType
			)
			SET @ScannedOsVendor = ISNULL(
				@ScannedOsVendor, @OldScannedOsVendor
			)
			SET @ScannedOsFamily = ISNULL(
				@ScannedOsFamily, @OldScannedOsFamily
			)
			SET @ScannedOsGen = ISNULL(
				@ScannedOsGen, @OldScannedOsGen
			)
			SET @ScannedMacAddress = ISNULL(
				@ScannedMacAddress, @OldScannedMacAddress
			)
			SET @ScannedMacVendor = ISNULL(
				@ScannedMacVendor, @OldScannedMacVendor
			)

			SET @SNMP_snmpCommunityString = ISNULL(
				@SNMP_snmpCommunityString, @OldSNMP_snmpCommunityString
			)
			SET @SNMP_sysDescr = ISNULL(
				@SNMP_sysDescr, @OldSNMP_sysDescr
			)
			SET @SNMP_sysObjectID = ISNULL(
				@SNMP_sysObjectID, @OldSNMP_sysObjectID
			)
			SET @SNMP_sysObjectIDSymbolic = ISNULL(
				@SNMP_sysObjectIDSymbolic, @OldSNMP_sysObjectIDSymbolic
			)
			SET @SNMP_sysUpTime = ISNULL(
				@SNMP_sysUpTime, @OldSNMP_sysUpTime
			)
			SET @SNMP_sysContact = ISNULL(
				@SNMP_sysContact, @OldSNMP_sysContact
			)
			SET @SNMP_sysName = ISNULL(
				@SNMP_sysName, @OldSNMP_sysName
			)
			SET @SNMP_sysLocation = ISNULL(
				@SNMP_sysLocation, @OldSNMP_sysLocation
			)
			SET @SNMP_sysServices = ISNULL(
				@SNMP_sysServices, @OldSNMP_sysServices
			)
			SET @SNMP_ipForwarding = ISNULL(
				@SNMP_ipForwarding, @OldSNMP_ipForwarding
			)

			SET @AMT_Secure = ISNULL(
				@AMT_Secure, @OldAMT_Secure
			)
			SET @AMT_Description = ISNULL(
				@AMT_Description, @OldAMT_Description
			)

			SET @Virtualization_Protocol = ISNULL(
				@Virtualization_Protocol, @OldVirtualization_Protocol
			)
			SET @Virtualization_Port = ISNULL(
				@Virtualization_Port, @OldVirtualization_Port
			)
			SET @Virtualization_APIType = ISNULL(
				@Virtualization_APIType, @OldVirtualization_APIType
			)
			SET @Virtualization_APIVersion = ISNULL(
				@Virtualization_APIVersion, @OldVirtualization_APIVersion
			)
			SET @Virtualization_NameID = ISNULL(
				@Virtualization_NameID, @OldVirtualization_NameID
			)
			SET @Virtualization_Version = ISNULL(
				@Virtualization_Version, @OldVirtualization_Version
			)

			-- Fetch next row
			FETCH NEXT FROM DuplicateCursor
			INTO	@OldDeviceID,
				@OldDuplicateID,
				@OldComputerID,
				@OldDeviceName,
				@OldDNSFullName,
				@OldNTDomainName,
				@OldIPAddress,
				@OldIPSubnet,
				@OldIPSubnetMask,
				@OldPhysicalAddress,
				@OldDeviceRole,
				@OldOperatingSystem,
				@OldOperatingSystemID,
				@OldIsManaged,
				@OldDescription,
				@OldSystemDescription,
				@OldSystemLocation,
				@OldSystemContact,
				@OldFirstDiscovered,
				@OldLastUpdate,
				@OldLastDataSourceName,
				@OldLastDataSourceType,

				@OldOpenPortsTCP,
				@OldOpenPortsUDP,
				@OldScannedOperatingSystem,

				@OldScannedOsType,
				@OldScannedOsVendor,
				@OldScannedOsFamily,
				@OldScannedOsGen,
				@OldScannedMacAddress,
				@OldScannedMacVendor,

				@OldSNMP_snmpCommunityString,
				@OldSNMP_sysDescr,
				@OldSNMP_sysObjectID,
				@OldSNMP_sysObjectIDSymbolic,
				@OldSNMP_sysUpTime,
				@OldSNMP_sysContact,
				@OldSNMP_sysName,
				@OldSNMP_sysLocation,
				@OldSNMP_sysServices,
				@OldSNMP_ipForwarding,

				@OldAMT_Secure,
				@OldAMT_Description,

				@OldVirtualization_Protocol,
				@OldVirtualization_Port,
				@OldVirtualization_APIType,
				@OldVirtualization_APIVersion,
				@OldVirtualization_NameID,
				@OldVirtualization_Version

			IF @@FETCH_STATUS <> 0
				BREAK

			-- Delete all but first row

			-- We are about to delete the primary device so
			-- make the first matching device the new
			-- primary device
			IF (@OldDeviceID = @PrimaryDeviceID)
				SET @PrimaryDeviceID = @FirstDeviceID

			-- Redirect any references stopping us from
			-- deleting row
			UPDATE	NetworkDevice
			SET	DuplicateID = @FirstDeviceID
			WHERE	DuplicateID = @OldDeviceID

			-- Delete DiscoveredBy information for the device
			DELETE FROM NetworkDeviceDiscoveredBy
			WHERE NetworkDeviceDiscoveredBy.DeviceID = @OldDeviceID
			AND NOT EXISTS(
				SELECT ActionApplies.DeviceID
				FROM ActionApplies
				WHERE ActionApplies.DeviceID = @OldDeviceID
			)

			DELETE FROM NetworkDeviceParent
			WHERE (DeviceID = @OldDeviceID OR ParentDeviceID = @OldDeviceID)
			AND NOT EXISTS(
				SELECT ActionApplies.DeviceID
				FROM ActionApplies
				WHERE ActionApplies.DeviceID = @OldDeviceID
			)
			
			-- Delete row
			DELETE FROM NetworkDevice
			WHERE NetworkDevice.DeviceID = @OldDeviceID
			AND NOT EXISTS(
				SELECT ActionApplies.DeviceID
				FROM ActionApplies
				WHERE ActionApplies.DeviceID = @OldDeviceID
			)
		END

		-- Update primary row
		UPDATE	NetworkDevice
		SET	DuplicateID = NULLIF(@PrimaryDeviceID, DeviceID),
			ComputerID = @ComputerID,
			DeviceName = @DeviceName,
			DNSFullName = @DNSFullName,
			NTDomainName = @NTDomainName,
			IPAddress = @IPAddress,
			IPSubnet = @IPSubnet,
			IPSubnetMask = @IPSubnetMask,
			PhysicalAddress = @PhysicalAddress,
			DeviceRole = @DeviceRole,
			OperatingSystem = @OperatingSystem,
			OperatingSystemID = @OperatingSystemID,
			IsManaged = @IsManaged,
			Description = @Description,
			SystemDescription = @SystemDescription,
			SystemLocation = @SystemLocation,
			SystemContact = @SystemContact,
			FirstDiscovered = @FirstDiscovered,
			LastUpdate = GETDATE(),
			LastDataSourceName = @LastDataSourceName,
			LastDataSourceType = @LastDataSourceType,

			OpenPortsTCP = @OpenPortsTCP,
			OpenPortsUDP = @OpenPortsUDP,
			ScannedOperatingSystem = @ScannedOperatingSystem,

			ScannedOsType	= @ScannedOsType,
			ScannedOsVendor	= @ScannedOsVendor,
			ScannedOsFamily	= @ScannedOsFamily,
			ScannedOsGen	= @ScannedOsGen,
			ScannedMacAddress	= @ScannedMacAddress,
			ScannedMacVendor	= @ScannedMacVendor,
			
			SQLDiscoveredBy = CASE WHEN @IsSQL = 0 THEN '' ELSE
								CASE WHEN ISNULL(@IsSQL, -1) = -1 THEN SQLDiscoveredBy ELSE @SQLDiscoveredBy END
							END,
			SQLPorts = CASE WHEN @IsSQL = 0 THEN '' ELSE
								CASE WHEN ISNULL(@IsSQL, -1) = -1 THEN SQLPorts ELSE @SQLPorts END
							END
			
		WHERE DeviceID = @FirstDeviceID
		
		IF (@IsSQL <> -1)
		BEGIN
			exec NetworkDeviceCalculateMembers @FirstDeviceID
		END

		-- Delete any SNMP info for this device and then repopulate
		-- if necessary
		DELETE FROM NetworkDeviceSNMPInfo
			WHERE DeviceID = @FirstDeviceID

		IF (
			@SNMP_snmpCommunityString IS NOT NULL OR
			@SNMP_sysDescr IS NOT NULL OR
			@SNMP_sysObjectID IS NOT NULL OR
			@SNMP_sysObjectIDSymbolic IS NOT NULL OR
			@SNMP_sysUpTime IS NOT NULL OR
			@SNMP_sysContact IS NOT NULL OR
			@SNMP_sysName IS NOT NULL OR
			@SNMP_sysLocation IS NOT NULL OR
			@SNMP_sysServices IS NOT NULL OR
			@SNMP_ipForwarding IS NOT NULL
		)
		BEGIN
			INSERT INTO NetworkDeviceSNMPInfo
			(
				DeviceID,
				SNMP_snmpCommunityString,
				SNMP_sysDescr,
				SNMP_sysObjectID,
				SNMP_sysObjectIDSymbolic,
				SNMP_sysUpTime,
				SNMP_sysContact,
				SNMP_sysName,
				SNMP_sysLocation,
				SNMP_sysServices,
				SNMP_ipForwarding
			)
			VALUES (
				@FirstDeviceID,
				@SNMP_snmpCommunityString,
				@SNMP_sysDescr,
				@SNMP_sysObjectID,
				@SNMP_sysObjectIDSymbolic,
				@SNMP_sysUpTime,
				@SNMP_sysContact,
				@SNMP_sysName,
				@SNMP_sysLocation,
				@SNMP_sysServices,
				@SNMP_ipForwarding
			)
		END

		-- Delete any AMT info for this device and then repopulate
		-- if necessary
		DELETE FROM NetworkDeviceAMTInfo
		WHERE DeviceID = @FirstDeviceID

		IF (
			@AMT_Secure IS NOT NULL OR
			@AMT_Description IS NOT NULL
		)
		BEGIN
			INSERT INTO NetworkDeviceAMTInfo
			(
				DeviceID,
				Secure,
				Description
			)
			VALUES (
				@FirstDeviceID,
				@AMT_Secure,
				@AMT_Description
			)
		END

		-- Delete any Virtualization info for this device and then repopulate
		-- if necessary
		DELETE FROM NetworkDeviceVirtualizationInfo
		WHERE DeviceID = @FirstDeviceID

		IF (
			@Virtualization_Protocol IS NOT NULL OR
			@Virtualization_Port IS NOT NULL OR
			@Virtualization_APIType IS NOT NULL OR
			@Virtualization_APIVersion IS NOT NULL OR
			@Virtualization_NameID IS NOT NULL OR
			@Virtualization_Version IS NOT NULL
		)
		BEGIN
			INSERT INTO NetworkDeviceVirtualizationInfo
			(
				DeviceID,
				Protocol,
				Port,
				APIType,
				APIVersion,
				ProductNameID,
				ProductVersion
			)
			VALUES (
				@FirstDeviceID,
				@Virtualization_Protocol,
				@Virtualization_Port,
				@Virtualization_APIType,
				@Virtualization_APIVersion,
				@Virtualization_NameID,
				@Virtualization_Version
			)
		END

	END
	ELSE
	BEGIN
		-- This is a new network device: insert new row
		INSERT INTO NetworkDevice
		(
			DuplicateID, ComputerID, DeviceName, DNSFullName,
			NTDomainName, IPAddress, IPSubnet,
			IPSubnetMask, PhysicalAddress, DeviceRole,
			OperatingSystem, OperatingSystemID, IsManaged,
			Description, SystemDescription, SystemLocation,
			SystemContact, LastDataSourceName, LastDataSourceType,

			OpenPortsTCP,
			OpenPortsUDP,
			ScannedOperatingSystem,

			ScannedOsType,
			ScannedOsVendor,
			ScannedOsFamily,
			ScannedOsGen,
			ScannedMacAddress,
			ScannedMacVendor,
			SQLDiscoveredBy,
			SQLPorts
		)
		VALUES (
			@PrimaryDeviceID, @ComputerID, @DeviceName, @DNSFullName,
			@NTDomainName, @IPAddress, @IPSubnet,
			@IPSubnetMask, @PhysicalAddress, @DeviceRole,
			@OperatingSystem, @OperatingSystemID, @IsManaged,
			@Description, @SystemDescription, @SystemLocation,
			@SystemContact, @LastDataSourceName, @LastDataSourceType,

			@OpenPortsTCP,
			@OpenPortsUDP,
			@ScannedOperatingSystem,

			@ScannedOsType,
			@ScannedOsVendor,
			@ScannedOsFamily,
			@ScannedOsGen,
			@ScannedMacAddress,
			@ScannedMacVendor,
			CASE WHEN ISNULL(@IsSQL, 0) = 0 THEN '' ELSE @SQLDiscoveredBy END,
			@SQLPorts
			
		)

		SET @FirstDeviceID = @@IDENTITY
		SET @PrimaryDeviceID = @FirstDeviceID
		
		IF (@IsSQL <> -1)
		BEGIN
			exec NetworkDeviceCalculateMembers @FirstDeviceID
		END

		-- Populate SNMP information if we have any
		IF (
			@SNMP_snmpCommunityString IS NOT NULL OR
			@SNMP_sysDescr IS NOT NULL OR
			@SNMP_sysObjectID IS NOT NULL OR
			@SNMP_sysObjectIDSymbolic IS NOT NULL OR
			@SNMP_sysUpTime IS NOT NULL OR
			@SNMP_sysContact IS NOT NULL OR
			@SNMP_sysName IS NOT NULL OR
			@SNMP_sysLocation IS NOT NULL OR
			@SNMP_sysServices IS NOT NULL OR
			@SNMP_ipForwarding IS NOT NULL
		)
		BEGIN
			INSERT INTO NetworkDeviceSNMPInfo
			(
				DeviceID,
				SNMP_snmpCommunityString,
				SNMP_sysDescr,
				SNMP_sysObjectID,
				SNMP_sysObjectIDSymbolic,
				SNMP_sysUpTime,
				SNMP_sysContact,
				SNMP_sysName,
				SNMP_sysLocation,
				SNMP_sysServices,
				SNMP_ipForwarding
			)
			VALUES (
				@FirstDeviceID,
			@SNMP_snmpCommunityString,
			@SNMP_sysDescr,
			@SNMP_sysObjectID,
			@SNMP_sysObjectIDSymbolic,
			@SNMP_sysUpTime,
			@SNMP_sysContact,
			@SNMP_sysName,
			@SNMP_sysLocation,
			@SNMP_sysServices,
			@SNMP_ipForwarding
		)
		END

		-- Populate AMT information if we have any
		IF (
			@AMT_Secure IS NOT NULL OR
			@AMT_Description IS NOT NULL
		)
		BEGIN
			INSERT INTO NetworkDeviceAMTInfo
			(
				DeviceID,
				Secure,
				Description
			)
			VALUES (
				@FirstDeviceID,
				@AMT_Secure,
				@AMT_Description
			)
		END

		-- Populate Virtualization information if we have any
		IF (
			@Virtualization_Protocol IS NOT NULL OR
			@Virtualization_Port IS NOT NULL OR
			@Virtualization_APIType IS NOT NULL OR
			@Virtualization_APIVersion IS NOT NULL OR
			@Virtualization_NameID IS NOT NULL OR
			@Virtualization_Version IS NOT NULL
		)
		BEGIN
			INSERT INTO NetworkDeviceVirtualizationInfo
			(
				DeviceID,
				Protocol,
				Port,
				APIType,
				APIVersion,
				ProductNameID,
				ProductVersion
			)
			VALUES (
				@FirstDeviceID,
				@Virtualization_Protocol,
				@Virtualization_Port,
				@Virtualization_APIType,
				@Virtualization_APIVersion,
				@Virtualization_NameID,
				@Virtualization_Version
			)
		END
	END

	-- Cleanup cursor
	CLOSE DuplicateCursor
	DEALLOCATE DuplicateCursor

	-- Check whether we have a better OperatingSystem value from Inventory:
	SELECT	@InvOperatingSystemID = OperatingSystemID
		FROM	Computer
		WHERE	ComputerID = @ComputerID
	IF (@InvOperatingSystemID IS NOT NULL)
	BEGIN
		-- If InvOperatingSystemID is better/more refined, use it instead
		SET @IsBetter = CASE WHEN (@OperatingSystemID IS NULL
					OR  @OperatingSystemID <= 1)
				THEN 1	-- Anything's better than NULL/unknown/other
				ELSE 0
				END
		IF @IsBetter = 0	--  Old may be better:
			-- If OldOperatingSystem looks ok, is it really better?
			EXEC @IsBetter = OperatingSystemCategoryTest
						@OperatingSystemID,
						@InvOperatingSystemID
		IF @IsBetter <> 0	-- Old definitely *is* better
		BEGIN
			SET @OperatingSystemID = @InvOperatingSystemID
			SELECT @OperatingSystem = OperatingSystemName
				FROM OperatingSystem
				WHERE OperatingSystemID = @OperatingSystemID

			UPDATE	NetworkDevice
			SET	OperatingSystem = @OperatingSystem,
				OperatingSystemID = @OperatingSystemID
			WHERE DeviceID = @FirstDeviceID
		END
	END
	ELSE IF (@OperatingSystemID IS NOT NULL)
	BEGIN
		UPDATE	Computer
		SET OperatingSystemID = @OperatingSystemID
		WHERE ComputerID = @ComputerID
	END

	-- Synchronize NULL entries in primary device
	IF (@PrimaryDeviceID IS NOT NULL AND @PrimaryDeviceID <> @FirstDeviceID)
	BEGIN
		UPDATE	NetworkDevice
		SET	ComputerID = ISNULL(ComputerID, @ComputerID),
			DeviceRole = ISNULL(DeviceRole, @DeviceRole),
			OperatingSystem = ISNULL(OperatingSystem, @OperatingSystem),
			OperatingSystemID = ISNULL(OperatingSystemID, @OperatingSystemID),
			IsManaged = ISNULL(IsManaged, @IsManaged),
			Description = ISNULL(Description, @Description),
			SystemDescription = ISNULL(SystemDescription, @SystemDescription),
			SystemLocation = ISNULL(SystemLocation, @SystemLocation),
			SystemContact = ISNULL(SystemContact, @SystemContact),

			OpenPortsTCP = ISNULL(OpenPortsTCP, @OpenPortsTCP),
			OpenPortsUDP = ISNULL(OpenPortsUDP, @OpenPortsUDP),
			ScannedOperatingSystem = ISNULL(ScannedOperatingSystem, @ScannedOperatingSystem),

			ScannedOsType = ISNULL(ScannedOsType, @ScannedOsType),
			ScannedOsVendor = ISNULL(ScannedOsVendor, @ScannedOsVendor),
			ScannedOsFamily = ISNULL(ScannedOsFamily, @ScannedOsFamily),
			ScannedOsGen	 = ISNULL(ScannedOsGen	, @ScannedOsGen	),
			ScannedMacAddress = ISNULL(ScannedMacAddress, @ScannedMacAddress),
			ScannedMacVendor = ISNULL(ScannedMacVendor, @ScannedMacVendor)
		WHERE DeviceID = @PrimaryDeviceID

		-- If no SNMP info for PrimaryDevice, but exists for FirstDevice then
		-- create row for PrimaryDevice, otherwise if exists for FirstDevice then
		-- update it, otherwise do nothing
		IF (
			NOT EXISTS(SELECT * FROM NetworkDeviceSNMPInfo WHERE DeviceID = @PrimaryDeviceID)
			AND EXISTS(SELECT * FROM NetworkDeviceSNMPInfo WHERE DeviceID = @FirstDeviceID)
		)
		BEGIN
			INSERT INTO NetworkDeviceSNMPInfo
			(
				DeviceID,
				SNMP_snmpCommunityString,
				SNMP_sysDescr,
				SNMP_sysObjectID,
				SNMP_sysObjectIDSymbolic,
				SNMP_sysUpTime,
				SNMP_sysContact,
				SNMP_sysName,
				SNMP_sysLocation,
				SNMP_sysServices,
				SNMP_ipForwarding
			)
			VALUES (
				@PrimaryDeviceID,
				@SNMP_snmpCommunityString,
				@SNMP_sysDescr,
				@SNMP_sysObjectID,
				@SNMP_sysObjectIDSymbolic,
				@SNMP_sysUpTime,
				@SNMP_sysContact,
				@SNMP_sysName,
				@SNMP_sysLocation,
				@SNMP_sysServices,
				@SNMP_ipForwarding
			)
		END
		ELSE IF (
			EXISTS(SELECT * FROM NetworkDeviceSNMPInfo WHERE DeviceID = @PrimaryDeviceID)
		)
		BEGIN
			UPDATE	NetworkDeviceSNMPInfo
			SET
			SNMP_snmpCommunityString = ISNULL(SNMP_snmpCommunityString, @SNMP_snmpCommunityString),
			SNMP_sysDescr = ISNULL(SNMP_sysDescr, @SNMP_sysDescr),
			SNMP_sysObjectID = ISNULL(SNMP_sysObjectID, @SNMP_sysObjectID),
			SNMP_sysObjectIDSymbolic = ISNULL(SNMP_sysObjectIDSymbolic, @SNMP_sysObjectIDSymbolic),
			SNMP_sysUpTime = ISNULL(SNMP_sysUpTime, @SNMP_sysUpTime),
			SNMP_sysContact = ISNULL(SNMP_sysContact, @SNMP_sysContact),
			SNMP_sysName = ISNULL(SNMP_sysName, @SNMP_sysName),
			SNMP_sysLocation = ISNULL(SNMP_sysLocation, @SNMP_sysLocation),
			SNMP_sysServices = ISNULL(SNMP_sysServices, @SNMP_sysServices),
			SNMP_ipForwarding = ISNULL(SNMP_ipForwarding, @SNMP_ipForwarding)
			WHERE DeviceID = @PrimaryDeviceID
		END

		-- If no AMT info for PrimaryDevice, but exists for FirstDevice then
		-- create row for PrimaryDevice, otherwise if exists for FirstDevice then
		-- update it, otherwise do nothing
		IF (
			NOT EXISTS(SELECT * FROM NetworkDeviceAMTInfo WHERE DeviceID = @PrimaryDeviceID)
			AND EXISTS(SELECT * FROM NetworkDeviceAMTInfo WHERE DeviceID = @FirstDeviceID)
		)
		BEGIN
			INSERT INTO NetworkDeviceAMTInfo
			(
				DeviceID,
				Secure,
				Description
			)
			VALUES (
				@PrimaryDeviceID,
				@AMT_Secure,
				@AMT_Description
			)
		END
		ELSE IF (
			EXISTS(SELECT * FROM NetworkDeviceAMTInfo WHERE DeviceID = @PrimaryDeviceID)
		)
		BEGIN
			UPDATE	NetworkDeviceAMTInfo
			SET
				Secure = ISNULL(Secure, @AMT_Secure),
				Description = ISNULL(Description, @AMT_Description)
		WHERE DeviceID = @PrimaryDeviceID
		END

		-- If no Virtualization info for PrimaryDevice, but exists for FirstDevice then
		-- create row for PrimaryDevice, otherwise if exists for FirstDevice then
		-- update it, otherwise do nothing
		IF (
			NOT EXISTS(SELECT * FROM NetworkDeviceVirtualizationInfo WHERE DeviceID = @PrimaryDeviceID)
			AND EXISTS(SELECT * FROM NetworkDeviceVirtualizationInfo WHERE DeviceID = @FirstDeviceID)
		)
		BEGIN
			INSERT INTO NetworkDeviceVirtualizationInfo
			(
				DeviceID,
				Protocol,
				Port,
				APIType,
				APIVersion,
				ProductNameID,
				ProductVersion
			)
			VALUES (
				@PrimaryDeviceID,
				@Virtualization_Protocol,
				@Virtualization_Port,
				@Virtualization_APIType,
				@Virtualization_APIVersion,
				@Virtualization_NameID,
				@Virtualization_Version
			)
		END
		ELSE IF (
			EXISTS(SELECT * FROM NetworkDeviceVirtualizationInfo WHERE DeviceID = @PrimaryDeviceID)
		)
		BEGIN
			UPDATE	NetworkDeviceVirtualizationInfo
			SET
				Protocol = ISNULL(Protocol, @Virtualization_Protocol),
				Port = ISNULL(Port, @Virtualization_Port),
				APIType = ISNULL(APIType, @Virtualization_APIType),
				APIVersion = ISNULL(APIVersion, @Virtualization_APIVersion),
				ProductNameID = ISNULL(ProductNameID, @Virtualization_NameID),
				ProductVersion = ISNULL(ProductVersion, @Virtualization_Version)
		WHERE DeviceID = @PrimaryDeviceID
		END
	END


	-- Now we need to create/update the NetworkDeviceDiscoveredBy
	-- entry for this device.
	IF (@DiscoveringServerUID IS NOT NULL)
	BEGIN
		DECLARE @DiscoveredByLastUpate DATETIME
		SET @DiscoveredByLastUpate = GETDATE()

		-- if there already exists a record for this device we simply
		-- update it with new values
		if (EXISTS(SELECT * FROM NetworkDeviceDiscoveredBy
			WHERE ServerUID = @DiscoveringServerUID AND DeviceID = @FirstDeviceID))
		BEGIN
			-- leave CanAdminister unchanged
			IF (@DiscoveringServerCanAdminister = 2)
				SELECT @DiscoveringServerCanAdminister = CanAdminister
					FROM NetworkDeviceDiscoveredBy
					WHERE ServerUID = @DiscoveringServerUID AND DeviceID = @FirstDeviceID

			EXEC NetworkDeviceDiscoveredByUpdateByDeviceIDServerUID
				@FirstDeviceID,
				@DiscoveringServerUID,
				@DiscoveringServerCanAdminister,
				@DiscoveredByLastUpate,
				@AccountID
		END
		ELSE
		BEGIN
			-- we need to create a new discovered by record
			IF (@DiscoveringServerCanAdminister = 2)
				SET @DiscoveringServerCanAdminister = 0

			EXEC NetworkDeviceDiscoveredByAdd
				@FirstDeviceID,
				@DiscoveringServerUID,
				@DiscoveringServerCanAdminister,
				@DiscoveredByLastUpate,
				@AccountID
		END
	END

	IF (@PrimaryDeviceID IS NOT NULL)
	BEGIN
		SET @DeviceID_OUT = @PrimaryDeviceID
	END
	ELSE
	BEGIN
		SET @DeviceID_OUT = @FirstDeviceID
	END

	COMMIT TRANSACTION
END
GO

-- Create UpdateNetworkDeviceIsManaged stored procedure
PRINT 'Creating procedure to update network discovery managed devices'
IF EXISTS(SELECT * FROM sysobjects WHERE xtype = 'P'
	AND name = 'UpdateNetworkDeviceIsManaged'
)
	DROP PROCEDURE UpdateNetworkDeviceIsManaged
GO
CREATE PROCEDURE UpdateNetworkDeviceIsManaged
AS
BEGIN
	--Determine if the device is managed. A device is managed if
	--it has Software in its inventory with a software name of
	--"ManageSoft for managed devices" or "ManageSoft for
	--distribution servers" of version 7.5 or greater

	print 'Updating IsManaged'

	DECLARE @IsManagedObsoletePeriod AS int;

	SELECT @IsManagedObsoletePeriod = Value
			FROM DatabaseConfiguration
			WHERE Property = 'IsManagedObsoletePeriod'
	IF @IsManagedObsoletePeriod IS NULL
			SELECT @IsManagedObsoletePeriod = 30

	UPDATE	NetworkDevice
	SET	IsManaged = CASE WHEN
		(i.Reported IS NOT NULL) OR (ir.SWDate IS NOT NULL AND so.SoftwareID IS NOT NULL)
					THEN 1 ELSE 0 END
	FROM NetworkDevice nd
	LEFT OUTER JOIN InventoryReport AS ir
		ON ir.ComputerID = nd.ComputerID
		AND ir.UserID = 1
		-- No recent inventory report
		AND ( DATEADD(DAY,@IsManagedObsoletePeriod,ir.SWDate) > GETDATE() )

	LEFT OUTER JOIN (
		SoftwareOccurrence AS so
		INNER JOIN SoftwareVersion AS sv
		ON so.SoftwareID = sv.SoftwareID
		AND (
			sv.SoftwareName = 'ManageSoft for managed devices'
			OR sv.SoftwareName = 'ManageSoft' --Unix client
			OR sv.SoftwareName = 'managesoft.rte' --AIX client
			OR	(
				sv.SoftwareName = 'ManageSoft for distribution servers'
				AND (sv.Version LIKE '7[,.][56789]%'
					OR sv.Version LIKE '8[,.]%')
			)
		)
	)
		ON nd.ComputerID = so.ComputerID
		AND so.UserID = 1

	-- No installation data shows ManageSoft is installed
	-- more recently than the last software inventory above
	LEFT OUTER JOIN	(
		Installation AS i
		INNER JOIN PackageVersion AS pv
		ON i.PackageVersionID = pv.PackageVersionID
		AND ( DATEADD(DAY,@IsManagedObsoletePeriod,i.Reported) > GETDATE() )
		AND (
			pv.Title LIKE 'ManageSoft for%managed devices'
			OR	(
				pv.Title = 'ManageSoft for distribution servers'
				AND (pv.Version LIKE '7[,.][56789]%'
					OR pv.Version LIKE '8[,.]%')
			)
		)
	)
		ON i.ComputerID = nd.ComputerID
		AND i.UserID = 1
		AND ( ir.SWDate IS NULL OR ir.SWDate <= i.Reported )

	-- No adoption happened since the last data we have
	WHERE NOT EXISTS (
		SELECT *
			FROM ActionApplies AS aa, [Action] As a, Task, TaskType
			WHERE aa.DeviceID = nd.DeviceID
			AND ( DATEADD(DAY,@IsManagedObsoletePeriod,aa.LastUpdate) > GETDATE() )
			AND ( ir.SWDate IS NULL OR ir.SWDate <= aa.LastUpdate )
			AND ( i.Reported IS NULL OR i.Reported <= aa.LastUpdate )
	 		AND a.TaskID = Task.TaskID
			AND Task.TaskTypeID = TaskType.TaskTypeID
			AND aa.ActionUID = a.ActionUID
			AND TaskType.TaskTypeName = 'Adoption'
		)

	OPTION (MAXDOP 1)

END
GO

-- Create UpdateNetworkDeviceServices stored procedure
PRINT 'Creating procedure to update network discovery device services'
IF EXISTS(SELECT * FROM sysobjects WHERE xtype = 'P'
	AND name = 'UpdateNetworkDeviceServices'
)
	DROP PROCEDURE UpdateNetworkDeviceServices
GO
CREATE PROCEDURE UpdateNetworkDeviceServices
	@ComputerID INT = NULL
AS
BEGIN
	--Determine if the device is running VMware etc
	--services based on hardware inventory

	CREATE TABLE #VMServers (
		ComputerID	int NOT NULL,
		Protocol	varchar(16) COLLATE database_default,
		Port		int NOT NULL,
		APIType		varchar(32) COLLATE database_default,
		APIVersion	varchar(16) COLLATE database_default,
		ProductName	nvarchar(256) COLLATE database_default,
		ProductVersion	varchar(16) COLLATE database_default
	)

	INSERT INTO #VMServers
	SELECT	hosdk.ComputerID,
		dbo.CIMString(hvProtocol.Value)
			AS Protocol,
		ISNULL(dbo.CIMInteger(hvPort.Value), 0)
			AS Port,
		dbo.CIMString(hvAPIType.Value)
			AS APIType,
		dbo.CIMString(hvAPIVersion.Value)
			AS APIVersion,
		dbo.CIMString(hvName.Value)
			AS [Name],
		dbo.CIMString(hvVersion.Value)
			AS Version

	FROM	HardwareObject AS hosdk

		INNER JOIN HardwareClass AS hcsdk
		ON hcsdk.HardwareClassID = hosdk.HardwareClassID
		AND hcsdk.Class IN ('MGSVM_InfrastructureSDK', 'VMWARE_InfrastructureSDK')

		INNER JOIN HardwareClass AS hcos
		ON hcos.Class IN ('MGSVM_InfrastructureSDK', 'VMWARE_OperatingSystem')

		INNER JOIN HardwareObject AS hoos
		ON hoos.ComputerID = hosdk.ComputerID
		AND hcos.HardwareClassID = hoos.HardwareClassID

		LEFT OUTER JOIN HardwareProperty AS hpName
		ON hpName.Property = 'Name'
		LEFT OUTER LOOP JOIN HardwareValue AS hvName
		ON hoos.HardwareObjectID = hvName.HardwareObjectID
		AND hpName.HardwarePropertyID = hvName.HardwarePropertyID

		LEFT OUTER JOIN HardwareProperty AS hpVersion
		ON hpVersion.Property = 'Version'
		LEFT OUTER LOOP JOIN HardwareValue AS hvVersion
		ON hoos.HardwareObjectID = hvVersion.HardwareObjectID
		AND hpVersion.HardwarePropertyID = hvVersion.HardwarePropertyID

		LEFT OUTER JOIN HardwareProperty AS hpAPIType
		ON hpAPIType.Property = 'APIType'
		LEFT OUTER LOOP JOIN HardwareValue AS hvAPIType
		ON hoos.HardwareObjectID = hvAPIType.HardwareObjectID
		AND hpAPIType.HardwarePropertyID = hvAPIType.HardwarePropertyID
		LEFT OUTER LOOP JOIN HardwareValue AS hvSDKAPIType
		ON hosdk.HardwareObjectID = hvSDKAPIType.HardwareObjectID
		AND hpAPIType.HardwarePropertyID = hvSDKAPIType.HardwarePropertyID

		LEFT OUTER JOIN HardwareProperty AS hpAPIVersion
		ON hpAPIVersion.Property = 'APIVersion'
		LEFT OUTER LOOP JOIN HardwareValue AS hvAPIVersion
		ON hoos.HardwareObjectID = hvAPIVersion.HardwareObjectID
		AND hpAPIVersion.HardwarePropertyID = hvAPIVersion.HardwarePropertyID

		LEFT OUTER JOIN HardwareProperty AS hpProtocol
		ON hpProtocol.Property = 'Protocol'
		LEFT OUTER LOOP JOIN HardwareValue AS hvProtocol
		ON hosdk.HardwareObjectID = hvProtocol.HardwareObjectID
		AND hpProtocol.HardwarePropertyID = hvProtocol.HardwarePropertyID
		-- Only store protocol if communicating with ESX directly
		AND ISNULL(hvAPIType.Value, '') = ISNULL(hvSDKAPIType.Value, '')

		LEFT OUTER JOIN HardwareProperty AS hpPort
		ON hpPort.Property = 'Port'
		LEFT OUTER LOOP JOIN HardwareValue AS hvPort
		ON hpPort.HardwarePropertyID = hvPort.HardwarePropertyID
		AND (
			(
			 -- Use SDK port value if direct to ESX
			 ISNULL(hvAPIType.Value, '') = ISNULL(hvSDKAPIType.Value, '')
			 AND hosdk.HardwareObjectID = hvPort.HardwareObjectID
			) OR (
			 -- Use OS port value if via VC
			 ISNULL(hvAPIType.Value, '') <> ISNULL(hvSDKAPIType.Value, '')
			 AND hoos.HardwareObjectID = hvPort.HardwareObjectID
			)
		)
	WHERE @ComputerID IS NULL OR hosdk.ComputerID = @ComputerID

	INSERT INTO VirtualizationProductName ( ProductName )
		SELECT DISTINCT ProductName FROM #VMServers
		WHERE ProductName NOT IN
		 (SELECT ProductName FROM VirtualizationProductName)

	UPDATE ndvi
	SET
		Protocol = vms.Protocol,
		Port = vms.Port,
		APIType = vms.APIType,
		APIVersion = vms.APIVersion,
		ProductNameID = vpn.VirtualizationProductNameID,
		ProductVersion = vms.ProductVersion

	FROM	NetworkDeviceVirtualizationInfo ndvi

		INNER JOIN NetworkDevice nd
		ON nd.DeviceID = ndvi.DeviceID

		INNER JOIN #VMServers vms
		ON vms.ComputerID = nd.ComputerID

		INNER JOIN VirtualizationProductName vpn
		ON vpn.ProductName = vms.ProductName

	INSERT INTO NetworkDeviceVirtualizationInfo (
		DeviceID,
		Protocol,
		Port,
		APIType,
		APIVersion,
		ProductNameID,
		ProductVersion
	)
		SELECT
			nd.DeviceID,
			vms.Protocol,
			vms.Port,
			vms.APIType,
			vms.APIVersion,
			vpn.VirtualizationProductNameID,
			vms.ProductVersion

		FROM	#VMServers vms

			INNER JOIN VirtualizationProductName vpn
			ON vpn.ProductName = vms.ProductName

			INNER JOIN NetworkDevice nd
			ON nd.ComputerID = vms.ComputerID
			AND nd.DuplicateID IS NULL
			AND nd.DeviceID NOT IN (
			  SELECT DeviceID FROM NetworkDeviceVirtualizationInfo
			)

END
GO

-- Create UpdateNetworkDevices stored procedure stored procedure
PRINT 'Creating procedure to update network discovery devices'
IF EXISTS(SELECT * FROM sysobjects WHERE xtype = 'P'
	AND name = 'UpdateNetworkDevices'
)
	DROP PROCEDURE UpdateNetworkDevices
GO
CREATE PROCEDURE UpdateNetworkDevices
AS
BEGIN
	SELECT ComputerID, MACAddress, IPAddress
	INTO #nac
	FROM NetworkAdapterConfiguration nac
	WHERE MACAddress IS NOT NULL OR IPAddress IS NOT NULL

	SELECT ComputerID, CSName
	INTO #cos
	FROM ComputerOperatingSystem

	-- Remove links with deleted computers
	UPDATE NetworkDevice
	SET NetworkDevice.ComputerID = NULL
	FROM NetworkDevice AS N
	LEFT OUTER JOIN Computer AS C
	ON N.ComputerID = C.ComputerID
	WHERE N.ComputerID IS NOT NULL
	AND C.ComputerID IS NULL

	-- Link inventory with discovery via MAC address and computer name
	UPDATE NetworkDevice
	SET	NetworkDevice.ComputerID = H1.ComputerID
	FROM #cos AS H2
	INNER JOIN #nac AS H1
	ON H1.ComputerID = H2.ComputerID
	INNER JOIN NetworkDevice AS N
	ON H1.MACAddress = N.PhysicalAddress AND H2.CSName = N.DeviceName
	WHERE N.ComputerID IS NULL

	-- Link inventory with discovery via MAC address and IP address
	UPDATE NetworkDevice
	SET	NetworkDevice.ComputerID = H.ComputerID
	FROM NetworkDevice AS N
	INNER JOIN #nac AS H
	ON H.MACAddress = N.PhysicalAddress AND H.IPAddress = N.IPAddress
	WHERE N.ComputerID IS NULL

	-- Link inventory with discovery via computer name
	UPDATE NetworkDevice
	SET NetworkDevice.ComputerID = H.ComputerID
	FROM NetworkDevice AS N
	INNER JOIN #cos AS H
	ON H.CSName = N.DeviceName
	WHERE N.ComputerID IS NULL
	AND N.PhysicalAddress IS NULL

	-- Link inventory with discovery via IP address
	UPDATE NetworkDevice
	SET NetworkDevice.ComputerID = H.ComputerID
	FROM NetworkDevice AS N
	INNER JOIN #nac AS H
	ON H.IPAddress = N.IPAddress
	WHERE N.ComputerID IS NULL
	AND N.PhysicalAddress IS NULL
	AND N.DeviceName IS NULL

	-- Update device names
	UPDATE NetworkDevice
	SET NetworkDevice.DeviceName = C.ComputerCN
	FROM NetworkDevice AS N
	INNER JOIN Computer AS C
	ON N.ComputerID = C.ComputerID
	WHERE N.DeviceName <> C.ComputerCN

	-- Update operating system
	UPDATE Computer
	SET Computer.OperatingSystemID = N.OperatingSystemID
	FROM NetworkDevice AS N
	INNER JOIN Computer AS C
	ON N.ComputerID = C.ComputerID
	WHERE C.OperatingSystemID IS NULL

	EXEC UpdateNetworkDeviceIsManaged

	EXEC UpdateNetworkDeviceServices

	-- Update any ActionApplies records with a new ComputerID as necessary.
	UPDATE ActionApplies
	SET	ComputerID = nd.ComputerID
	FROM ActionApplies AS aa
	INNER JOIN NetworkDevice AS nd
	ON aa.DeviceID = nd.DeviceID
END
GO

-- Create LinkNetworkDevice stored procedure
PRINT 'Creating procedure to link a network device with a computer'
IF EXISTS(SELECT * FROM sysobjects WHERE xtype = 'P'
	AND name = 'LinkNetworkDevice'
)
	DROP PROCEDURE LinkNetworkDevice
GO
CREATE PROCEDURE LinkNetworkDevice
	@DeviceID int,
	@ComputerID int
AS
BEGIN
	UPDATE NetworkDevice
	SET ComputerID = @ComputerID
	WHERE DeviceID = @DeviceID
END
GO

-- Create ClearNetworkDevices stored procedure
PRINT 'Creating procedure to clear discovery information'
IF EXISTS(SELECT * FROM sysobjects WHERE xtype = 'P'
	AND name = 'ClearNetworkDevices'
)
	DROP PROCEDURE ClearNetworkDevices
GO
CREATE PROCEDURE ClearNetworkDevices
	@LastDataSourceName nvarchar(128) = NULL,
	@LastDataSourceType nvarchar(32) = NULL
AS
BEGIN
	BEGIN TRANSACTION

	-- Delete NetworkDeviceDiscoveredBy entries that rely on network devices that will be deleted
	DELETE NetworkDeviceDiscoveredBy FROM NetworkDeviceDiscoveredBy
	INNER JOIN NetworkDevice ON NetworkDeviceDiscoveredBy.DeviceID = NetworkDevice.DeviceID
	WHERE (@LastDataSourceName IS NULL OR (@LastDataSourceName = NetworkDevice.LastDataSourceName))
	AND (@LastDataSourceType IS NULL OR (@LastDataSourceType = NetworkDevice.LastDataSourceType))
	AND NOT EXISTS(
		SELECT ActionApplies.DeviceID FROM ActionApplies
		WHERE ActionApplies.DeviceID = NetworkDevice.DeviceID
	)
	
	-- Delete matching network devices, but not ones with an outstanding action
	DELETE FROM NetworkDevice
	WHERE (@LastDataSourceName IS NULL OR (@LastDataSourceName = LastDataSourceName))
	AND (@LastDataSourceType IS NULL OR (@LastDataSourceType = LastDataSourceType))
	AND NOT EXISTS(
		SELECT ActionApplies.DeviceID FROM ActionApplies
		WHERE ActionApplies.DeviceID = NetworkDevice.DeviceID
	)

	COMMIT TRANSACTION
END
GO

PRINT 'Creating procedure to clear discovery record'
IF EXISTS(SELECT * FROM sysobjects WHERE xtype = 'P'
	AND name = 'RemoveNetworkDevice'
)
	DROP PROCEDURE RemoveNetworkDevice
GO
CREATE PROCEDURE RemoveNetworkDevice
	@NetworkDeviceID	int,
	@ClearActionApplies	bit
AS
BEGIN
BEGIN TRANSACTION

	IF @ClearActionApplies = 1
	BEGIN
		-- Delete ActionApplies entries that rely on the network device that will be deleted
		DELETE ActionApplies FROM ActionApplies
		INNER JOIN NetworkDevice ON ActionApplies.DeviceID = NetworkDevice.DeviceID
		WHERE (@NetworkDeviceID = NetworkDevice.DeviceID) or
			(@NetworkDeviceID = NetworkDevice.DuplicateID)
	END

	-- Delete NetworkDeviceDiscoveredBy entries that rely on the network device that will be deleted
	DELETE NetworkDeviceDiscoveredBy FROM NetworkDeviceDiscoveredBy
	INNER JOIN NetworkDevice ON NetworkDeviceDiscoveredBy.DeviceID = NetworkDevice.DeviceID
	WHERE	(
			(@NetworkDeviceID = NetworkDevice.DeviceID) or
			(@NetworkDeviceID = NetworkDevice.DuplicateID)
		)
	  AND	(
			@ClearActionApplies = 1 OR
			NOT EXISTS (
				SELECT	*
				FROM	ActionApplies
				WHERE	ActionApplies.DeviceID IN (
					SELECT	DeviceID
					FROM	NetworkDevice AS nd2
					WHERE	(@NetworkDeviceID = nd2.DeviceID) or
						(@NetworkDeviceID = nd2.DuplicateID)
				)
			)
		)

	-- Clean up NetworkDeviceParent table
	DELETE FROM NetworkDeviceParent
	WHERE	(
			(@NetworkDeviceID = NetworkDeviceParent.DeviceID) or
			(@NetworkDeviceID = NetworkDeviceParent.ParentDeviceID) or
			EXISTS (
				SELECT * FROM NetworkDevice as nd
				WHERE nd.DuplicateID = @NetworkDeviceID AND
					(nd.DeviceID = NetworkDeviceParent.DeviceID OR
					nd.DeviceID = NetworkDeviceParent.ParentDeviceID)
			)
		)
		AND	(
			@ClearActionApplies = 1 OR
			NOT EXISTS (
				SELECT	*
				FROM	ActionApplies
				WHERE	ActionApplies.DeviceID IN (
					SELECT	DeviceID
					FROM	NetworkDevice AS nd2
					WHERE	(@NetworkDeviceID = nd2.DeviceID) or
						(@NetworkDeviceID = nd2.DuplicateID)
				)
			)
		)

	DELETE FROM KnownOracleService
	WHERE DeviceID = @NetworkDeviceID

	DELETE FROM KnownOracleListener
	WHERE DeviceID = @NetworkDeviceID

	-- Delete matching network devices, but not ones with an outstanding action
	DELETE FROM NetworkDevice
	WHERE	(
			(@NetworkDeviceID = NetworkDevice.DeviceID) or
			(@NetworkDeviceID = NetworkDevice.DuplicateID)
		)
	  AND	(
			@ClearActionApplies = 1 OR
			NOT EXISTS (
				SELECT	*
				FROM	ActionApplies
				WHERE	ActionApplies.DeviceID IN (
					SELECT	DeviceID
					FROM	NetworkDevice AS nd2
					WHERE	(@NetworkDeviceID = nd2.DeviceID) or
						(@NetworkDeviceID = nd2.DuplicateID)
				)
			)
		)

	COMMIT TRANSACTION
END
GO

-- Create PopulateNetworkDevices stored procedure
PRINT 'Creating procedure to populate discovery information'
IF EXISTS(SELECT * FROM sysobjects WHERE xtype = 'P'
	AND name = 'PopulateNetworkDevices'
)
	DROP PROCEDURE PopulateNetworkDevices
GO
CREATE PROCEDURE PopulateNetworkDevices
AS
BEGIN

	DECLARE @ComputerID AS INT
	DECLARE @DeviceName AS NVARCHAR(64)
	DECLARE @IPAddress AS VARCHAR(64)
	DECLARE @IPSubnetMask AS VARCHAR(64)
	DECLARE @PhysicalAddress AS VARCHAR(64)
	DECLARE @DNSFullName AS VARCHAR(513)
	DECLARE @OperatingSystemID AS INTEGER
	DECLARE @ScannedOperatingSystem AS VARCHAR(513)
	DECLARE @IsDefaultIPGatewaySet AS BIT

	DECLARE @ParentDeviceID AS INT
	DECLARE @ParentComputerID AS INT
	DECLARE @DeviceID_OUT AS INT

	-- Create temp table for network devices
	CREATE TABLE #NetworkDevice (
		ComputerID int NULL,
		DeviceName nvarchar(64) COLLATE database_default NULL,
		IPAddress varchar(64) COLLATE database_default NULL,
		IPSubnetMask varchar(64) COLLATE database_default NULL,
		PhysicalAddress varchar(64) COLLATE database_default NULL,
		DNSFullName varchar(513) COLLATE database_default NULL,
		OperatingSystemID int NULL,
		ScannedOperatingSystem varchar (512) COLLATE database_default NULL,
		ParentComputerID int NULL,
		IsDefaultIPGatewaySet bit
	)

	-- Populate temp table from inventory
	PRINT 'Reading device information from inventory'
	INSERT INTO #NetworkDevice
	SELECT	C.ComputerID,
		C.ComputerCN AS DeviceName,
		LEFT (IPAddress, PATINDEX('%,%', IPAddress + ',') - 1) AS IPAddress,
		LEFT (IPSubnet, PATINDEX('%,%', IPSubnet + ',') - 1) AS IPSubnetMask,
		LEFT (MACAddress, 64) AS PhysicalAddress,
		DNSHostName + '.' + DNSDomain AS DNSFullName,
		C.OperatingSystemID,
		NULL AS ScannedOperatingSystem, --ScannedOperatingSystem
		NULL AS ParentComputerID, --ParentComputerID
		IsDefaultIPGatewaySet = CASE
			WHEN DefaultIPGateway IS NULL THEN 0
			ELSE 1
		END
	FROM	Computer AS C
		INNER JOIN NetworkAdapterConfiguration A
			ON A.ComputerID = C.ComputerID
	WHERE	IPAddress IS NOT NULL
	  AND	LEFT (IPAddress, PATINDEX('%,%', IPAddress + ',') - 1) <> '0.0.0.0'
	  AND	LEFT (IPSubnet, PATINDEX('%,%', IPSubnet + ',') - 1) IS NOT NULL
      AND	LEFT (IPAddress, PATINDEX('%,%', IPAddress + ',') - 1) NOT LIKE '127.%'
	  AND	MACAddress IS NOT NULL

	-- Populate virtual machines from inventory into temp table
	DECLARE VirtualMachineCursor CURSOR STATIC FOR
	SELECT
		LEFT (HostName, PATINDEX('%.%', HostName + '.') - 1) as DeviceName,
		IPAddress,
		MACAddress as PhysicalAddress, --PhysicalAddress
		HostName as DNSFullName, --DNSFullName
		GuestFullName as ScannedOperatingSystem,
		ComputerID AS ParentComputerID
	FROM VirtualMachineView
	WHERE (HostName IS NOT NULL OR IPAddress IS NOT NULL) AND
		LOWER(ISNULL(HostName, '')) <> 'unknown' AND
		ISNULL(IPAddress, '') <> '0.0.0.0'
	OPEN VirtualMachineCursor

	FETCH NEXT FROM VirtualMachineCursor
		INTO	@DeviceName,
				@IPAddress,
				@PhysicalAddress,				
				@DNSFullName,
				@ScannedOperatingSystem,
				@ParentComputerID
	WHILE @@FETCH_STATUS = 0
	BEGIN
		DECLARE @FirstMAC AS VARCHAR(64)
		DECLARE @RemainingMACs AS VARCHAR(64)
		DECLARE @FirstSeparator AS INT

		SET @RemainingMACs = ISNULL(@PhysicalAddress, '')

		WHILE (@RemainingMACs IS NOT NULL)
		BEGIN

			SET @FirstMAC = LEFT (@RemainingMACs, PATINDEX('%;%', @RemainingMACs + ';') - 1)

			INSERT INTO #NetworkDevice
			VALUES
			(
				NULL, --ComputerID
				@DeviceName,
				@IPAddress,
				NULL, --IPSubnetMask
				@FirstMAC, --PhysicalAddress
				@DNSFullName, --DNSFullName
				NULL, --OperatingSystemID
				@ScannedOperatingSystem,
				@ParentComputerID,
				1 --IsDefaultGatewaySet
			)

			SET @FirstSeparator = PATINDEX('%;%', @RemainingMACs)
			IF (@FirstSeparator = 0)
			BEGIN
				SET @RemainingMACs = NULL
			END
			ELSE
				SET @RemainingMACs = RIGHT (@RemainingMACs, LEN (@RemainingMACs) - PATINDEX('%;%', @RemainingMACs + ';'))
		END

	FETCH NEXT FROM VirtualMachineCursor
		INTO	@DeviceName,
				@IPAddress,
				@PhysicalAddress,				
				@DNSFullName,
				@ScannedOperatingSystem,
				@ParentComputerID
	END
	CLOSE VirtualMachineCursor
	DEALLOCATE VirtualMachineCursor
	
	-- Create index
	CREATE CLUSTERED INDEX [TempNetworkDevice]
		ON #NetworkDevice (PhysicalAddress)

	DELETE n1
	FROM #NetworkDevice n1, #NetworkDevice n2
	WHERE n1.PhysicalAddress = n2.PhysicalAddress
	  AND n1.ComputerID <> n2.ComputerID

	-- Delete parent child relations for devices being deleted
	DELETE NetworkDeviceParent
	FROM
		( SELECT NetworkDevice.DeviceID
			FROM NetworkDevice,
			( SELECT DeviceID
				FROM NetworkDevice
			WHERE LastDataSourceName = 'CoreDS'
			  AND LastDataSourceType = 'Inventory'
			  AND NOT EXISTS(
				SELECT ComputerID FROM #NetworkDevice as t
				WHERE LOWER(NetworkDevice.PhysicalAddress) = LOWER(t.PhysicalAddress)
				  AND ISNULL(NetworkDevice.DNSFullName, '') = ISNULL(t.DNSFullName, '')
			  )
			  AND NOT EXISTS(
				SELECT * FROM ActionApplies as a
				WHERE NetworkDevice.DeviceID = a.DeviceID
					OR NetworkDevice.DuplicateID = a.DeviceID
			  )
			) AS NetworkDeviceToDelete
		WHERE	(
				NetworkDevice.DeviceID = NetworkDeviceToDelete.DeviceID
				OR NetworkDevice.DuplicateID = NetworkDeviceToDelete.DeviceID
			)
			AND NOT EXISTS (
				SELECT DeviceID
				FROM NetworkDevice AS nd2
				WHERE nd2.DuplicateID = NetworkDeviceToDelete.DeviceID
			)
		) AS NetworkDeviceParentToDelete
	WHERE NetworkDeviceParent.DeviceID = NetworkDeviceParentToDelete.DeviceID
		OR NetworkDeviceParent.ParentDeviceID = NetworkDeviceParentToDelete.DeviceID

	-- Removing old devices
	PRINT 'Deleting old devices'
	DELETE NetworkDevice
	FROM
		( SELECT DeviceID
			FROM NetworkDevice
		WHERE LastDataSourceName = 'CoreDS'
		  AND LastDataSourceType = 'Inventory'
		  AND NOT EXISTS(
			SELECT ComputerID FROM #NetworkDevice as t
			WHERE LOWER(NetworkDevice.PhysicalAddress) = LOWER(t.PhysicalAddress)
			  AND ISNULL(NetworkDevice.DNSFullName, '') = ISNULL(t.DNSFullName, '')
		)
		  AND NOT EXISTS(
			SELECT * FROM ActionApplies as a
			WHERE NetworkDevice.DeviceID = a.DeviceID
				OR NetworkDevice.DuplicateID = a.DeviceID
		)
		) AS NetworkDeviceToDelete
	WHERE	(
			NetworkDevice.DeviceID = NetworkDeviceToDelete.DeviceID
			OR NetworkDevice.DuplicateID = NetworkDeviceToDelete.DeviceID
		)
		AND NOT EXISTS (
			SELECT DeviceID
			FROM NetworkDevice AS nd2
			WHERE nd2.DuplicateID = NetworkDeviceToDelete.DeviceID
		)

	-- Updating existing devices
	PRINT 'Updating existing devices'
	UPDATE NetworkDevice
		SET	ComputerID = t.ComputerID,
			DeviceName = t.DeviceName,
			DNSFullName = t.DNSFullName,
			IPAddress = t.IPAddress,
			IPSubnetMask = t.IPSubnetMask,
			OperatingSystemID = t.OperatingSystemID,
			OperatingSystem = os.OperatingSystemName
		FROM #NetworkDevice AS t
		LEFT OUTER JOIN OperatingSystem os
			ON os.OperatingSystemID = t.OperatingSystemID
		WHERE LOWER(NetworkDevice.PhysicalAddress) = LOWER(t.PhysicalAddress)
		AND ISNULL(NetworkDevice.DNSFullName, '') = ISNULL(t.DNSFullName, '')
		AND t.IsDefaultIPGatewaySet = 1
		AND (
			ISNULL(NetworkDevice.ComputerID, -1) <> ISNULL(t.ComputerID, -1)
			OR ISNULL(NetworkDevice.DeviceName, '') <> ISNULL(t.DeviceName, '')
			OR ISNULL(NetworkDevice.IPAddress, '') <> ISNULL(t.IPAddress, '')
			OR ISNULL(NetworkDevice.IPSubnetMask, '') <> ISNULL(t.IPSubnetMask, '')
			OR ISNULL(NetworkDevice.OperatingSystemID, -1) <> ISNULL(t.OperatingSystemID, -1)
			OR ISNULL(NetworkDevice.OperatingSystem, '') <> ISNULL(os.OperatingSystemName, '')
		)

	DECLARE ParentComputerCursor CURSOR STATIC FOR
	SELECT n2.DeviceID, n1.ParentComputerID
	FROM #NetworkDevice n1, NetworkDevice n2
		WHERE LOWER(n2.PhysicalAddress) = LOWER(n1.PhysicalAddress)
		AND ISNULL(n2.DNSFullName, '') = ISNULL(n1.DNSFullName, '')
		AND n1.IsDefaultIPGatewaySet = 1
		AND n1.ParentComputerID IS NOT NULL
	OPEN ParentComputerCursor

	FETCH NEXT FROM ParentComputerCursor
		INTO	@DeviceID_OUT,
				@ParentComputerID
	WHILE @@FETCH_STATUS = 0
	BEGIN
		IF (@ParentComputerID IS NOT NULL)
		BEGIN			
			SELECT TOP 1 @ParentDeviceID = DeviceID
			FROM NetworkDevice
			WHERE ComputerID = @ParentComputerID

			IF (@DeviceID_OUT IS NOT NULL AND @ParentDeviceID IS NOT NULL)
			BEGIN			
				EXEC NetworkDeviceParentPutByDeviceIDParentDeviceID @DeviceID_OUT, @ParentDeviceID
			END
		END
	FETCH NEXT FROM ParentComputerCursor
		INTO	@DeviceID_OUT,
				@ParentComputerID
	END
	CLOSE ParentComputerCursor
	DEALLOCATE ParentComputerCursor
		
	DELETE n1
	FROM #NetworkDevice n1, NetworkDevice n2
	WHERE LOWER(n1.PhysicalAddress) = LOWER(n2.PhysicalAddress)
	  AND ISNULL(n1.DNSFullName, '') = ISNULL(n2.DNSFullName, '')

	-- Open cursor for temp network device table
	PRINT 'Adding new devices'
	DECLARE NetworkDeviceCursor CURSOR STATIC FOR
		SELECT ComputerID,
				DeviceName,
				IPAddress,
				IPSubnetMask,
				PhysicalAddress,
				DNSFullName,
				OperatingSystemID,
				ScannedOperatingSystem,
				ParentComputerID
		FROM #NetworkDevice as t
		WHERE t.IsDefaultIPGatewaySet = 1
	OPEN NetworkDeviceCursor

	-- Add each row from result set to Network Device table
	FETCH NEXT FROM NetworkDeviceCursor
		INTO	@ComputerID,
			@DeviceName,
			@IPAddress,
			@IPSubnetMask,
			@PhysicalAddress,
			@DNSFullName,
			@OperatingSystemID,
			@ScannedOperatingSystem,
			@ParentComputerID
	WHILE @@FETCH_STATUS = 0
	BEGIN

		-- Add network device
		EXEC AddNetworkDevice
			1,
			@ComputerID,
			@DeviceName,
			@DNSFullName,
			NULL,
			@IPAddress,
			NULL, -- No IP subnet
			@IPSubnetMask,
			@PhysicalAddress,
			0, -- Computer
			NULL, -- No operating system
			@OperatingSystemID,
			NULL, -- Is managed
			NULL, -- No description
			NULL, -- No system description
			NULL, -- No system location
			NULL, -- No system contact
			'CoreDS', -- Last data source name
			'Inventory', -- Last data source type
			NULL, -- No DiscoveringServerUID
			2, -- CanAdminister is unknown
			NULL, -- TCP ports are unknown
			NULL, -- UDP ports are unknown
			@ScannedOperatingSystem, -- ScannedOperatingSystem
			NULL, NULL, NULL, NULL, NULL, NULL, -- Scanning results
			NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -- SNMP results
			NULL, -- AccountID
			NULL, NULL, -- AMT
			NULL, NULL, NULL, NULL, NULL, NULL, -- V12N results
			NULL, NULL, NULL, -- SQL data
			
			@DeviceID_OUT OUTPUT -- NetworkDeviceID of new/existing record

			IF (@ParentComputerID IS NOT NULL)
			BEGIN			
				SELECT TOP 1 @ParentDeviceID = DeviceID
				FROM NetworkDevice
				WHERE ComputerID = @ParentComputerID

				IF (@DeviceID_OUT IS NOT NULL AND @ParentDeviceID IS NOT NULL)
				BEGIN			
					EXEC NetworkDeviceParentPutByDeviceIDParentDeviceID @DeviceID_OUT, @ParentDeviceID
				END
			END

		-- Fetch next row
		FETCH NEXT FROM NetworkDeviceCursor
		INTO	@ComputerID,
			@DeviceName,
			@IPAddress,
			@IPSubnetMask,
			@PhysicalAddress,
			@DNSFullName,
			@OperatingSystemID,
			@ScannedOperatingSystem,
			@ParentComputerID
	END
	CLOSE NetworkDeviceCursor
	DEALLOCATE NetworkDeviceCursor
	DROP TABLE #NetworkDevice

	EXEC UpdateNetworkDeviceIsManaged

	EXEC UpdateNetworkDeviceServices
END
GO

-- Create PopulateVirtualMachines stored procedure
PRINT 'Creating procedure to create network device records for virtual machines from inventory'
IF EXISTS(SELECT * FROM sysobjects WHERE xtype = 'P'
	AND name = 'PopulateVirtualMachines'
)
	DROP PROCEDURE PopulateVirtualMachines
GO
CREATE PROCEDURE PopulateVirtualMachines
	@ComputerID INT,
	@ParentDeviceID INT = NULL
AS
BEGIN
	DECLARE @DeviceName AS VARCHAR(513)
	DECLARE @DNSFullName AS VARCHAR(513)
	DECLARE @IPAddress AS VARCHAR(64)
	DECLARE @IPSubnetMask AS VARCHAR(64)
	DECLARE @PhysicalAddress AS VARCHAR(64)
	DECLARE @ScannedOperatingSystem AS VARCHAR(513)
	DECLARE @OperatingSystemID AS INT
	DECLARE @DeviceID_OUT AS INT

	DECLARE @FirstMAC AS VARCHAR(64)
	DECLARE @RemainingMACs AS VARCHAR(64)
	DECLARE @FirstSeparator AS INT
	
	IF (NOT EXISTS (SELECT DeviceID FROM NetworkDevice WHERE ComputerID = @ComputerID))
	BEGIN	  
		SELECT @DeviceName = C.ComputerCN,
		@IPAddress = LEFT (IPAddress, PATINDEX('%,%', IPAddress + ',') - 1),
		@IPSubnetMask = LEFT (IPSubnet, PATINDEX('%,%', IPSubnet + ',') - 1),
		@PhysicalAddress = LEFT (MACAddress, 64),
		@DNSFullName = DNSHostName + '.' + DNSDomain,
		@OperatingSystemID = C.OperatingSystemID,
		@ScannedOperatingSystem = C.OperatingSystemID
		FROM	Computer AS C
			INNER JOIN NetworkAdapterConfiguration A
				ON A.ComputerID = C.ComputerID
		WHERE	IPAddress IS NOT NULL
		  AND	LEFT (IPAddress, PATINDEX('%,%', IPAddress + ',') - 1) <> '0.0.0.0'
		  AND	LEFT (IPSubnet, PATINDEX('%,%', IPSubnet + ',') - 1) IS NOT NULL
		  AND	LEFT (IPAddress, PATINDEX('%,%', IPAddress + ',') - 1) NOT LIKE '127.%'
		  AND	MACAddress IS NOT NULL
		  AND	DefaultIPGateway IS NOT NULL
		  AND	C.ComputerID = @ComputerID

		EXEC AddNetworkDevice
			1,
			@ComputerID,
			@DeviceName,
			@DNSFullName,
			NULL,
			@IPAddress,
			NULL, -- No IP subnet
			@IPSubnetMask,
			@PhysicalAddress,
			0, -- Computer
			NULL, -- No operating system
			@OperatingSystemID,
			NULL, -- Is managed
			NULL, -- No description
			NULL, -- No system description
			NULL, -- No system location
			NULL, -- No system contact
			'CoreDS', -- Last data source name
			'Inventory', -- Last data source type
			NULL, -- No DiscoveringServerUID
			2, -- CanAdminister is unknown
			NULL, -- TCP ports are unknown
			NULL, -- UDP ports are unknown
			@ScannedOperatingSystem -- ScannedOperatingSystem
	END

	EXEC UpdateNetworkDeviceServices @ComputerID

	-- Populate virtual machines from inventory into temp table
	DECLARE NetworkDeviceCursor CURSOR STATIC FOR
	SELECT
		LEFT (HostName, PATINDEX('%.%', HostName + '.') - 1) as DeviceName,
		IPAddress,
		HostName as DNSFullName,
		MACAddress as PhysicalAddress,
		GuestFullName as ScannedOperatingSystem
	FROM VirtualMachineView
		WHERE ComputerID = @ComputerID AND
			(dbo.CIMString(HostName) IS NOT NULL OR dbo.CIMString(IPAddress) IS NOT NULL) AND
			LOWER(ISNULL(HostName, '')) <> 'unknown' AND
			ISNULL(IPAddress, '') <> '0.0.0.0'

	OPEN NetworkDeviceCursor

	FETCH NEXT FROM NetworkDeviceCursor
		INTO
			@DeviceName,
			@IPAddress,
			@DNSFullName,
			@PhysicalAddress,
			@ScannedOperatingSystem

	WHILE @@FETCH_STATUS = 0
	BEGIN

			SET @RemainingMACs = ISNULL(@PhysicalAddress, '')

			WHILE (@RemainingMACs IS NOT NULL)
			BEGIN

				SET @FirstMAC = LEFT (@RemainingMACs, PATINDEX('%;%', @RemainingMACs + ';') - 1)

				-- Call AddNetworkDevice
				EXEC AddNetworkDevice
					1,
					NULL, -- ComputerID
					@DeviceName,
					@DNSFullName, -- DNSFullName
					NULL,
					@IPAddress,
					NULL, -- No IP subnet
					NULL, -- IPSubnetMask
					@FirstMAC, -- PhysicalAddress
					0, -- Computer
					NULL, -- No operating system
					NULL, -- OperatingSystemID
					NULL, -- Is managed
					NULL, -- No description
					NULL, -- No system description
					NULL, -- No system location
					NULL, -- No system contact
					'CoreDS', -- Last data source name
					'Inventory', -- Last data source type
					NULL, -- No DiscoveringServerUID
					2, -- CanAdminister is unknown
					NULL, -- TCP ports are unknown
					NULL, -- UDP ports are unknown
					@ScannedOperatingSystem, -- ScannedOperatingSystem
					NULL, NULL, NULL, NULL, NULL, NULL, -- Scanning results
					NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -- SNMP results
					NULL, -- AccountID
					NULL, NULL, -- AMT
					NULL, NULL, NULL, NULL, NULL, NULL, -- V12N results
					NULL, NULL, NULL, -- SQL data
					
					@DeviceID_OUT OUTPUT -- NetworkDeviceID of new/existing record

				SET @FirstSeparator = PATINDEX('%;%', @RemainingMACs)
				IF (@FirstSeparator = 0)
				BEGIN
					SET @RemainingMACs = NULL
				END
				ELSE
					SET @RemainingMACs = RIGHT (@RemainingMACs, LEN (@RemainingMACs) - PATINDEX('%;%', @RemainingMACs + ';'))
				
				-- Update NetworkDeviceParent
				IF (@ParentDeviceID IS NULL OR NOT EXISTS (
						SELECT DeviceID FROM NetworkDevice
						WHERE DeviceID = @ParentDeviceID))
				BEGIN
					DECLARE @TempDeviceID INT
					SET @TempDeviceID = NULL
					SELECT TOP 1 @TempDeviceID = DeviceID
					FROM NetworkDevice
					WHERE ComputerID = @ComputerID AND DuplicateID IS NULL
					SET @ParentDeviceID = @TempDeviceID
				END

				-- Add the parent id link for the new device
				IF (@DeviceID_OUT IS NOT NULL AND @ParentDeviceID IS NOT NULL)
				BEGIN			
					EXEC NetworkDeviceParentPutByDeviceIDParentDeviceID @DeviceID_OUT, @ParentDeviceID

					-- Add the parent link for duplicates of the new device
					DECLARE @TempDuplicateID INT
					SET @TempDuplicateID = NULL
					SELECT @TempDuplicateID = DuplicateID
					FROM NetworkDevice
					WHERE DeviceID = @DeviceID_OUT

					IF (@TempDuplicateID IS NOT NULL)
					BEGIN
						EXEC NetworkDeviceParentPutByDeviceIDParentDeviceID @TempDuplicateID, @ParentDeviceID
					END

				END
		END

		FETCH NEXT FROM NetworkDeviceCursor
		INTO
			@DeviceName,
			@IPAddress,
			@DNSFullName,
			@PhysicalAddress,
			@ScannedOperatingSystem

	END
	CLOSE NetworkDeviceCursor
	DEALLOCATE NetworkDeviceCursor

END
GO

PRINT 'Creating procedure to find domains based on CanAdminister column'
IF EXISTS(SELECT * FROM sysobjects WHERE xtype = 'P'
	AND name = 'NTDomainNameGetAllByCanAdminister'
)
	DROP PROCEDURE NTDomainNameGetAllByCanAdminister
GO
CREATE PROCEDURE NTDomainNameGetAllByCanAdminister
	@CanAdminister	bit
AS
	SELECT DISTINCT NTDomainName
	FROM NetworkDevice AS nd, NetworkDeviceDiscoveredBy AS ndb, DistributionServer AS ds
	WHERE nd.DeviceID = ndb.DeviceID
	  AND ndb.CanAdminister = @CanAdminister

	RETURN @@ROWCOUNT
GO

PRINT 'Creating procedure to get all NetworkDevices and DiscoveredBy counts'
IF EXISTS(SELECT * FROM sysobjects WHERE xtype = 'P'
	AND name = 'NetworkDeviceGetAllWithDiscoveredByCounts'
)
	DROP PROCEDURE NetworkDeviceGetAllWithDiscoveredByCounts
GO
CREATE PROCEDURE NetworkDeviceGetAllWithDiscoveredByCounts
	@ignoreDuplicates	bit = 0,
	@discoveringGUID	binary(16) = NULL,
	@filterString		nvarchar(256) = '%'
AS
	SELECT	nde.*,
		ISNULL(nddbcnt.DiscoveredByCount, 0) AS DiscoveredByCount,
		ISNULL(nddbcnt.CanAdministerCount, 0) AS CanAdministerCount

	FROM	NetworkDeviceExtended AS nde
	LEFT OUTER JOIN
		(
			SELECT	nddb.DeviceID,
				COUNT(nddb.ServerUID) AS DiscoveredByCount,
				SUM(CONVERT(int, nddb.CanAdminister)) AS CanAdministerCount
			FROM	NetworkDeviceDiscoveredBy AS nddb
			GROUP BY nddb.DeviceID
		) AS nddbcnt ON nddbcnt.DeviceID = nde.DeviceID

	WHERE	(
			@ignoreDuplicates = 0
			OR nde.DuplicateID IS NULL
		)
	  AND	(
			@discoveringGUID IS NULL
			OR EXISTS(
				SELECT	*
				FROM	NetworkDeviceDiscoveredBy AS nddb2
				WHERE	nddb2.ServerUID = @discoveringGUID
				  AND	nddb2.DeviceID = nde.DeviceID
			)
		)
	  AND	(
			(@filterString = '%')

			OR

			(DeviceName LIKE '%' + @filterString + '%'
			OR DNSFullName LIKE '%' + @filterString + '%'
			OR IPAddress LIKE '%' + @filterString + '%')
		)

	RETURN @@ROWCOUNT
GO

PRINT 'Creating procedure to get a particular NetworkDeviceExtended object'
IF EXISTS(SELECT * FROM sysobjects WHERE xtype = 'P'
	AND name = 'NetworkDeviceExtendedGetByDeviceID'
)
	DROP PROCEDURE NetworkDeviceExtendedGetByDeviceID
GO
CREATE PROCEDURE NetworkDeviceExtendedGetByDeviceID
	@DeviceID	int
AS
	SELECT	*
	FROM	NetworkDeviceExtended AS nde
	WHERE	nde.DeviceID = @DeviceID

	RETURN @@ROWCOUNT
GO

PRINT 'Creating procedure to get all NetworkDevices and DiscoveredBy counts in a domain'
IF EXISTS(SELECT * FROM sysobjects WHERE xtype = 'P'
	AND name = 'NetworkDeviceGetByNTDomainNameWithDiscoveredByCounts'
)
	DROP PROCEDURE NetworkDeviceGetByNTDomainNameWithDiscoveredByCounts
GO
CREATE PROCEDURE NetworkDeviceGetByNTDomainNameWithDiscoveredByCounts
	@ignoreDuplicates	bit = 0,
	@discoveringGUID	binary(16) = NULL,
	@filterString		nvarchar(256) = '%',
	@domainName		nvarchar(256) = '%'
AS
	SELECT	nde.*,	
		ISNULL(nddbcnt.DiscoveredByCount, 0) AS DiscoveredByCount,
		ISNULL(nddbcnt.CanAdministerCount, 0) AS CanAdministerCount
	FROM	NetworkDeviceExtended AS nde
	LEFT OUTER JOIN
		(
			SELECT	nddb.DeviceID,
				COUNT(nddb.ServerUID) AS DiscoveredByCount,
				SUM(CONVERT(int, nddb.CanAdminister)) AS CanAdministerCount
			FROM	NetworkDeviceDiscoveredBy AS nddb
			GROUP BY nddb.DeviceID
		) AS nddbcnt ON nddbcnt.DeviceID = nde.DeviceID
	WHERE	(
			@ignoreDuplicates = 0
			OR nde.DuplicateID IS NULL
		)
	  AND	(
			@discoveringGUID IS NULL
			OR EXISTS(
				SELECT	*
				FROM	NetworkDeviceDiscoveredBy AS nddb2
				WHERE	nddb2.ServerUID = @discoveringGUID
				  AND	nddb2.DeviceID = nde.DeviceID
			)
		)
	  AND	(
			DeviceName LIKE '%' + @filterString + '%'
			OR DNSFullName LIKE '%' + @filterString + '%'
			OR IPAddress LIKE '%' + @filterString + '%'
		)
	  AND	nde.NTDomainName LIKE @domainName

	RETURN @@ROWCOUNT
GO

PRINT 'Creating procedure to get all Subnets filtered by a parameter'
IF EXISTS(SELECT * FROM sysobjects WHERE xtype = 'P'
	AND name = 'NetworkLocationGetByPartialName'
)
	DROP PROCEDURE NetworkLocationGetByPartialName
GO
CREATE PROCEDURE NetworkLocationGetByPartialName
	@filterString		nvarchar(256) = '%'
AS
	SELECT	*
	FROM	NetworkLocation
	WHERE	Name LIKE '%' + @filterString + '%'

	RETURN @@ROWCOUNT
GO

PRINT 'Creating procedure to get all Sites and Subnets, filtered by a parameter'
IF EXISTS(SELECT * FROM sysobjects WHERE xtype = 'P'
	AND name = 'NetworkLocationAndSubnetGetByPartialName'
)
	DROP PROCEDURE NetworkLocationAndSubnetGetByPartialName
GO
CREATE PROCEDURE NetworkLocationAndSubnetGetByPartialName
	@filterString		nvarchar(256) = '%'
AS
	SELECT	nl.NetworkLocationID,
		[Name],
		[DN],
		nl.AutoPopulated,
		nl.Enabled as NetworkLocationEnabled,
		sn.Enabled as SubnetEnabled,
		DomainID,
		SubnetID,
		IPSubnet,
		IPSubnetMask,
       		DomainID		
	FROM 		NetworkLocation AS nl 
	INNER JOIN	Subnet AS sn 
	ON 	(nl.NetworkLocationID = sn.NetworkLocationID)
	WHERE	[Name] LIKE '%' + @filterString + '%'

	RETURN @@ROWCOUNT
GO

PRINT 'Return all subnets that clash with a particular subnet, check only either AD sites or MGS sites'
IF EXISTS(SELECT * FROM sysobjects WHERE xtype = 'P'
	AND name = 'GetSubnetsClashingWithByDomainType'
)
	DROP PROCEDURE GetSubnetsClashingWithByDomainType
GO
CREATE PROCEDURE GetSubnetsClashingWithByDomainType
	@IPSubnet		nvarchar(256) = '',
	@IPSubnetMask		nvarchar(256) = '',
	@AutoPopulated		bit = 0/*'1': Check AD only, '0': Check MGS only*/
AS
	SELECT	*
	FROM 	Subnet
	WHERE	IPSubnet LIKE @IPSubnet AND
		IPSubnetMask LIKE @IPSubnetMask AND
		AutoPopulated = @AutoPopulated AND
		Enabled = 1 /*Only check against enabled subnet*/

	RETURN @@ROWCOUNT
GO

PRINT 'Return all sites that clash with a particular subnet'
IF EXISTS(SELECT * FROM sysobjects WHERE xtype = 'P'
	AND name = 'GetSitesClashingWith'
)
	DROP PROCEDURE GetSitesClashingWith
GO
CREATE PROCEDURE GetSitesClashingWith
	@IPSubnet		nvarchar(256) = '',
	@IPSubnetMask		nvarchar(256) = ''
AS
	SELECT nl.* FROM NetworkLocation as nl
	INNER JOIN(	
		SELECT	*
		FROM 	Subnet
		WHERE	IPSubnet LIKE @IPSubnet AND
			IPSubnetMask LIKE @IPSubnetMask AND
			Enabled = 1 /*Only check against enabled subnet*/
		) AS sub

	ON nl.NetworkLocationID = sub.NetworkLocationID;
	
	RETURN @@ROWCOUNT
GO

PRINT 'Return all sites and subnets that clash with a particular subnet'
IF EXISTS(SELECT * FROM sysobjects WHERE xtype = 'P'
	AND name = 'GetSitesAndSubnetsClashingWith'
)
	DROP PROCEDURE GetSitesAndSubnetsClashingWith
GO
CREATE PROCEDURE GetSitesAndSubnetsClashingWith
	@IPSubnet		nvarchar(256) = '',
	@IPSubnetMask		nvarchar(256) = ''
AS
	SELECT 	nl.NetworkLocationID,
		[Name],
		[DN],
		nl.AutoPopulated,
		nl.Enabled as NetworkLocationEnabled,
		sn.Enabled as SubnetEnabled,
		DomainID,
		SubnetID,
		IPSubnet,
		IPSubnetMask,
       		DomainID
	FROM NetworkLocation as nl
	INNER JOIN(	
		SELECT	*
		FROM 	Subnet
		WHERE	IPSubnet LIKE @IPSubnet AND
			IPSubnetMask LIKE @IPSubnetMask AND
			Enabled = 1 /*Only check against enabled subnet*/
		) AS sn

	ON nl.NetworkLocationID = sn.NetworkLocationID;
	
	RETURN @@ROWCOUNT
GO

PRINT 'Disable all subnets linked with a particular NetworkLocationID'
IF EXISTS(SELECT * FROM sysobjects WHERE xtype = 'P'
	AND name = 'DisableSubnetsByNetworkLocationID'
)
	DROP PROCEDURE DisableSubnetsByNetworkLocationID
GO
CREATE PROCEDURE DisableSubnetsByNetworkLocationID
	@NetworkLocationID	int
AS
	UPDATE	Subnet
	SET 	Enabled = 0
	WHERE	NetworkLocationID = @NetworkLocationID
	
	RETURN @@ROWCOUNT
GO

PRINT 'Enable all subnets linked with a particular NetworkLocationID'
IF EXISTS(SELECT * FROM sysobjects WHERE xtype = 'P'
	AND name = 'EnableSubnetsByNetworkLocationID'
)
	DROP PROCEDURE EnableSubnetsByNetworkLocationID
GO
CREATE PROCEDURE EnableSubnetsByNetworkLocationID
	@NetworkLocationID	int
AS
	UPDATE	Subnet
	SET 	Enabled = 1
	WHERE	NetworkLocationID = @NetworkLocationID
	
	RETURN @@ROWCOUNT
GO

PRINT 'Creating a stored procedure to get the network devices that match at least one of the three criteria: Name together with Domain, DNS and Physical Address'
IF EXISTS(SELECT * FROM sysobjects WHERE xtype = 'P'
	AND name = 'NetworkDeviceGetByNameAndDomainORDNSORPhysicalAddress'
)
	DROP PROCEDURE NetworkDeviceGetByNameAndDomainORDNSORPhysicalAddress
GO
CREATE PROCEDURE NetworkDeviceGetByNameAndDomainORDNSORPhysicalAddress
	@DeviceName NVARCHAR(64) = NULL,
	@NTDomainName NVARCHAR(256) = NULL,
	@DNSFullName NVARCHAR(256) = NULL,
	@PhysicalAddress VARCHAR(64) = NULL
AS
	SELECT 	DeviceID, DeviceName, NTDomainName, DNSFullName, PhysicalAddress, IPAddress
	FROM 	NetworkDevice
	WHERE	
		DuplicateID IS NULL 
		AND  (
		--For domain, treat NULL and empty string as being the same
		(DeviceName = @DeviceName AND ISNULL(NTDomainName, '') = ISNULL(@NTDomainName, '')) OR
		DNSFullName = @DNSFullName OR
		PhysicalAddress = @PhysicalAddress
		)
	
	RETURN @@ROWCOUNT
GO

PRINT 'Creating a stored procedure to return records from the NetworkDevice table that could be merged with a device defined by a given set of details'
IF EXISTS(SELECT * FROM sysobjects WHERE xtype = 'P'
	AND name = 'NetworkDeviceFindDuplicateToMergeWith'
)
	DROP PROCEDURE NetworkDeviceFindDuplicateToMergeWith
GO
CREATE PROCEDURE NetworkDeviceFindDuplicateToMergeWith
	@DeviceName NVARCHAR(64) = NULL,
	@NTDomainName NVARCHAR(256) = NULL,
	@DNSFullName NVARCHAR(256) = NULL,
	@PhysicalAddress VARCHAR(64) = NULL,
	@IPAddress NVARCHAR(64) = NULL
AS

	-- from this point downward, the logic is similar to creating the DuplicateCursor
	-- in AddNetworkDevice, except that we don't care about SNMP_sysName 
	SELECT	DeviceID, DeviceName, NTDomainName, DNSFullName, PhysicalAddress, IPAddress
	FROM	NetworkDevice
	WHERE	DuplicateID IS NULL
		AND (
			-- matching on PhysicalAddress REGARDLESS
			PhysicalAddress = @PhysicalAddress
			
			-- matching on DeviceName, if there are no contradictions
			OR (	DeviceName = @DeviceName
				AND (	-- no contradiction on DNSFullName
					@DNSFullName IS NULL
					OR DNSFullName IS NULL
					OR @DNSFullName = DNSFullName
				)
				AND (	-- no contradiction on NTDomainName
					@NTDomainName IS NULL
					OR NTDomainName IS NULL
					OR @NTDomainName = NTDomainName
				)
			)

			-- matching on DNSFullName, if there are no contradictions
			OR (	DNSFullName = @DNSFullName
				AND (	-- no contradiction on DeviceName
					@DeviceName IS NULL
					OR DeviceName IS NULL
					OR @DeviceName = DeviceName
				)
				AND (	-- no contradiction on NTDomainName
					@NTDomainName IS NULL
					OR NTDomainName IS NULL
					OR @NTDomainName = NTDomainName
				)
			)
			
			OR (	@IPAddress = IPAddress
				AND @DeviceName IS NULL 
				AND @DNSFullName IS NULL 
				AND @PhysicalAddress IS NULL
			)
			
			OR (	IPAddress = @IPAddress
				AND 
				(@DeviceName IS NOT NULL 
				OR @DNSFullName IS NOT NULL 
				OR @PhysicalAddress IS NOT NULL)
				AND DeviceName IS NULL
				AND DNSFullName IS NULL
				AND PhysicalAddress IS NULL
			)

		)

	RETURN @@ROWCOUNT
GO

PRINT 'Creating a stored procedure to update the NetworkDevice table and the AMT and Virtualization table for the scenario in which a network device is edited manually via the UI by the user.'
IF EXISTS(SELECT * FROM sysobjects WHERE xtype = 'P'
	AND name = 'NetworkDeviceUpdateManual'
)
	DROP PROCEDURE NetworkDeviceUpdateManual
GO
CREATE PROCEDURE NetworkDeviceUpdateManual
	@DeviceID INT = NULL,
	@DeviceName NVARCHAR(64) = NULL,
	@DNSFullName NVARCHAR(256) = NULL,
	@NTDomainName NVARCHAR(256) = NULL,
	@IPAddress VARCHAR(64) = NULL,
	@IPSubnetMask VARCHAR(64) = NULL,
	@PhysicalAddress VARCHAR(64) = NULL,
	@IsManaged INT = NULL,
	@IsAMTDevice INT = NULL,-- 1: true, 0: false, -1: unchanged
	@IsVirtualizationDevice INT = NULL,-- 1: true, 0: false, -1: unchanged
	@VirtualizationProductNameID INT = NULL,
	@VirtualizationPort INT = NULL,
	@IsSQL INT = NULL

AS
	BEGIN TRANSACTION

	UPDATE 	NetworkDevice
	SET	DeviceName = @DeviceName,
		NTDomainName = @NTDomainName,
		DNSFullName = @DNSFullName,
		IPAddress = @IPAddress,
		IPSubnetMask = @IPSubnetMask,
		PhysicalAddress = @PhysicalAddress,
		IsManaged = @IsManaged,
		LastDataSourceName = 'CoreDS',
		LastDataSourceType = 'Manual',
		SQLDiscoveredBy =
			CASE WHEN ISNULL(@IsSQL, -1) = -1 THEN SQLDiscoveredBy ELSE
				(CASE WHEN @IsSQL = 0 THEN '' ELSE
					(CASE WHEN ISNULL(SQLDiscoveredBy, '') = '' THEN 'Manual' ELSE SQLDiscoveredBy END)
				END)
			END,
		SQLPorts = CASE WHEN @IsSQL = 0 THEN '' ELSE SQLPorts END
	WHERE	DeviceID = @DeviceID

	IF (@IsAMTDevice = 0)
	BEGIN
		DELETE FROM NetworkDeviceAMTInfo
		WHERE DeviceID = @DeviceID
	END
	ELSE IF (@IsAMTDevice = 1)
	BEGIN
		INSERT INTO NetworkDeviceAMTInfo (DeviceID, Secure, Description)
		VALUES (@DeviceID, NULL, 'Intel(R) Active Management Technology')
		--This procedure will crash if the user tries to make a device an AMT device
		--when it already is an AMT device
	END
	
	IF (@IsVirtualizationDevice = 0) --If Virtualization setting has changed and the device is no longer a virtualization device then remove it
	BEGIN
		DELETE FROM NetworkDeviceVirtualizationInfo --Leave the VirtualizationProductName record intact in even if there's nothing linked to it (?)
		WHERE DeviceID = @DeviceID
	END
	ELSE IF (@IsVirtualizationDevice = 1) --If Virtualization setting has changed and the device is still a virtualization device...
	BEGIN
		--If the device was already a virtualization device before the change then the change only applies to ProductNameID or Port fields
		IF EXISTS (SELECT * FROM NetworkDeviceVirtualizationInfo WHERE DeviceID = @DeviceID)
		BEGIN
			--So update them
			UPDATE NetworkDeviceVirtualizationInfo
			SET 
				ProductNameID = @VirtualizationProductNameID,
				Port = @VirtualizationPort
			WHERE	DeviceID = @DeviceID
		END
		ELSE --If the device wasn't a virtualization device before the change then simply add a new record to NetworkDeviceVirtualizationInfo
		BEGIN
			INSERT INTO NetworkDeviceVirtualizationInfo (DeviceID, ProductNameID, Port)
			VALUES (@DeviceID, @VirtualizationProductNameID, @VirtualizationPort)
			--Note that the NetworkDeviceVirtualizationInfo table is design to allow a device to have different product name.
			--This procedure will still crash if the record being added violates the primary key constraints.
		END
		--Also note that this procedure assumes that a device cannot have more than one product name
	END

	IF (@IsSQL <> -1)
	BEGIN
		exec NetworkDeviceCalculateMembers @DeviceID
	END


	COMMIT TRANSACTION

	RETURN @@ROWCOUNT
GO

PRINT 'Creating a stored procedure to remove all KnownService records for a particular device, that were not manually added'
IF EXISTS(SELECT * FROM sysobjects WHERE xtype = 'P'
	AND name = 'KnownOracleServicesRemoveNonManualAddsByDeviceID'
)
	DROP PROCEDURE KnownOracleServicesRemoveNonManualAddsByDeviceID
GO
CREATE PROCEDURE KnownOracleServicesRemoveNonManualAddsByDeviceID
	@DeviceID int
AS
	DELETE FROM KnownOracleService
	WHERE	DeviceID = @DeviceID AND
		ManuallyAdded = 0 

	DELETE FROM KnownOracleListener

	FROM KnownOracleListener as kol
	WHERE	DeviceID = @DeviceID AND
		ManuallyAdded = 0 AND NOT EXISTS (
			SELECT * FROM KnownOracleService as kos
			WHERE kos.KnownOracleListenerID = kol.KnownOracleListenerID )
GO

PRINT 'Creating a stored procedure that populates the NetworkDeviceCalculatedMember table for a device'
IF EXISTS(SELECT * FROM sysobjects WHERE xtype = 'P'
	AND name = 'NetworkDeviceCalculateMembers'
)
	DROP PROCEDURE NetworkDeviceCalculateMembers
GO
CREATE PROCEDURE NetworkDeviceCalculateMembers
	@DeviceID int
AS

	IF NOT EXISTS(
		SELECT *
		FROM NetworkDevice as nd
		WHERE nd.DeviceID = @DeviceID
	)
	BEGIN
		RETURN 1
	END

	DECLARE @OracleListeners AS NVARCHAR(512)
	DECLARE @OracleServices AS NVARCHAR(512)

	SET @OracleListeners = ''
	SET @OracleServices = ''

	DECLARE OracleListenerCursor CURSOR STATIC FOR
	SELECT
		kol.KnownOracleListenerID,
		kol.[Name],
		kol.Port
	FROM KnownOracleListener as kol
	WHERE
		kol.DeviceID = @DeviceID
		
	OPEN OracleListenerCursor

	DECLARE @ListenerID AS INT
	DECLARE @ListenerName AS NVARCHAR(64)
	DECLARE @ListenerPort AS NVARCHAR(64)

	FETCH NEXT FROM OracleListenerCursor
	INTO
		@ListenerID,
		@ListenerName,
		@ListenerPort
	WHILE @@FETCH_STATUS = 0
	BEGIN

		DECLARE @PortNumber AS NVARCHAR(16)
		DECLARE @ListenerString AS NVARCHAR(80)

		SET @ListenerString = @ListenerName + ':' + @ListenerPort

		IF (@OracleListeners = '')
		BEGIN
			SET @OracleListeners = @ListenerString
		END
		ELSE
			SET @OracleListeners = @OracleListeners + ',' + @ListenerString
		
		FETCH NEXT FROM OracleListenerCursor
		INTO
			@ListenerID,
			@ListenerName,
			@ListenerPort
	END

	CLOSE OracleListenerCursor
	DEALLOCATE OracleListenerCursor

	DECLARE OracleServiceCursor CURSOR STATIC FOR
	SELECT kos.[Name]
	FROM KnownOracleService as kos
	WHERE
		kos.DeviceID = @DeviceID

	OPEN OracleServiceCursor

	DECLARE @KnownServiceName AS NVARCHAR(64)

	FETCH NEXT FROM OracleServiceCursor
	INTO @KnownServiceName
	WHILE @@FETCH_STATUS = 0
	BEGIN
		
		IF (@OracleServices = '')
		BEGIN
			SET @OracleServices = @KnownServiceName
		END
		ELSE
			SET @OracleServices = @OracleServices + ',' + @KnownServiceName
		
		FETCH NEXT FROM OracleServiceCursor
		INTO @KnownServiceName
	END

	CLOSE OracleServiceCursor
	DEALLOCATE OracleServiceCursor

	DECLARE @IsOracle bit
	IF (@OracleListeners = '') AND (@OracleServices = '')
	BEGIN	
		SET @IsOracle = 0
	END
	ELSE
		SET @IsOracle = 1

	DECLARE @IsSQL bit
	SELECT @IsSQL = (case when ISNULL(nd.SQLDiscoveredBy, '') <> '' then 1 else 0 end)
	FROM NetworkDevice as nd
	WHERE nd.DeviceID = @DeviceID

	IF EXISTS (
		SELECT *
		FROM NetworkDeviceCalculatedMember as ndcm
		WHERE ndcm.DeviceID = @DeviceID
	)
	BEGIN
		UPDATE NetworkDeviceCalculatedMember
		SET
			IsOracle = @IsOracle,
			OracleListeners = @OracleListeners,
			OracleServices = @OracleServices,
			IsSQL = @IsSQL
		WHERE DeviceID = @DeviceID
	END
	ELSE
	BEGIN
		INSERT INTO NetworkDeviceCalculatedMember
		(
			DeviceID,
			IsOracle,
			OracleListeners,
			OracleServices,
			IsSQL
		)
		VALUES
		(
			@DeviceID,
			@IsOracle,
			@OracleListeners,
			@OracleServices,
			@IsSQL
		)
	END
GO
/*
 * $Id: PolicyBootstrap.sql 90026 2008-10-29 00:58:01Z pca $
 *
 * Stored Procedures to bootstrap policy for newly-discovered devices.
 *
 * Copyright 2000-2002 ManageSoft Corporation. All rights reserved.
 * Reproduction, adaptation, or translation without prior permission
 * is prohibited.
 */

-- Populate a table of the ancestor organizations of the given Organization
-- The table #OrganizationAncestry must be created before calling, as:
-- CREATE TABLE #OrganizationAncestry (OrganizationID int, RDN nvarchar(400), InheritanceBlocked bit);
IF EXISTS(SELECT * FROM sysobjects WHERE xtype = 'P'
		AND name = 'OrganizationIdentifyByAncestry')
	DROP  PROCEDURE OrganizationIdentifyByAncestry
GO
CREATE PROCEDURE OrganizationIdentifyByAncestry
	@OrganizationID	int
AS
	DECLARE	@DomainID	int
	DECLARE @OURDN		nvarchar(400)
	DECLARE	@BlockInheritance bit
	DECLARE	@ChildBlockInheritance bit
	SET	@ChildBlockInheritance = 0

	SELECT	@DomainID = o.DomainID,
		@OURDN = o.RDN,
		@BlockInheritance = o.BlockInheritance
	FROM	Organization as o
	WHERE	@OrganizationID = o.OrganizationID

	DECLARE	@i int
	WHILE @OURDN IS NOT NULL
	BEGIN
		IF @OrganizationID IS NOT NULL
			INSERT #OrganizationAncestry VALUES(@OrganizationID, @OURDN, @ChildBlockInheritance)
	
		SET @i = charindex(',', @OURDN)
		IF (len(@OURDN) = 0)
			SET @OURDN = NULL
		ELSE IF (@i = 0)
			SET @OURDN = ''
		ELSE
			SET @OURDN = stuff(@OURDN, 1, @i, '')
	
		SET @ChildBlockInheritance = @BlockInheritance
		SELECT	@OrganizationID = OrganizationID,
			@BlockInheritance = BlockInheritance | @BlockInheritance
		FROM	Organization
		WHERE	@OURDN = RDN
		  AND	@DomainID = DomainID
	END
GO

/*
 * Populate a table of all policies that apply to the given organization
 * The table #PolicyOU must be created before calling, as:
	CREATE TABLE #PolicyByOU (
		GUID binary(16),
		AccessGroupID int,
		OrganizationID int,
		NoOverride bit,
		EnabledForComputers bit,
		EnabledForUsers bit
	);
 */
IF EXISTS(SELECT * FROM sysobjects WHERE xtype = 'P'
		AND name = 'PolicyIdentifyByOrganization')
	DROP PROCEDURE PolicyIdentifyByOrganization
GO
CREATE PROCEDURE PolicyIdentifyByOrganization
	@OrganizationID	int
AS
	DECLARE	@DomainID	int
	DECLARE @OURDN		nvarchar(400)

	SELECT	@DomainID = o.DomainID,
		@OURDN = o.RDN
	FROM	Organization as o
	WHERE	@OrganizationID = o.OrganizationID

	-- Find all ancestor Organizations up to the domain:
	CREATE TABLE #OrganizationAncestry (
		OrganizationID int,
		RDN nvarchar(400) COLLATE database_default,
		InheritanceBlocked bit
	);
	EXEC OrganizationIdentifyByAncestry @OrganizationID
	-- SELECT * FROM #OrganizationAncestry order by RDN

	INSERT #PolicyByOU
	SELECT	p.GUID,
		p.AccessGroupID,
		o.OrganizationID,
		CASE WHEN m.MemberMode > 1 THEN 1 ELSE 0 END,
		p.EnabledForComputers,
		p.EnabledForUsers
	FROM	#OrganizationAncestry o,
		Policy as p,
		[Group] as g,
		Member as m
	WHERE	o.OrganizationID = m.TargetID	-- This organization
	  and	m.TargetTypeID = 8	-- is a member
	  and	m.MemberMode <> 0	-- not blocked
	  and	m.GroupID = g.GroupID	-- of the AccessGroup
	  and	g.GroupID = p.AccessGroupID -- for a Policy
	  and	(o.InheritanceBlocked = 0 OR m.MemberMode > 1)
	  and not exists(	-- Same policy applying to a child OU
		SELECT *
		FROM	#OrganizationAncestry co, -- Child organization
			Member as cm
		WHERE	g.GroupID = cm.GroupID	-- the policy AccessGroup
		  and	cm.TargetID = co.OrganizationID	-- has a member
		  and	cm.TargetTypeID = 8	-- organization
		  and	cm.MemberMode <> 0	-- not blocked
		  and	len(co.RDN) > len(o.RDN)-- which is a child OU
		)

	DROP TABLE #OrganizationAncestry
GO

-- The specified computer has just been added to Active Directory.
-- Find all policies that apply to the OU where it belongs, and
-- make sure that this computer has PolicyApplies records for them.
IF EXISTS(SELECT * FROM sysobjects WHERE xtype = 'P'
		AND name = 'PolicyAppliesBootstrapComputer')
	DROP PROCEDURE PolicyAppliesBootstrapComputer
GO
CREATE PROCEDURE PolicyAppliesBootstrapComputer
	@ComputerID	int
AS
	DECLARE @OrganizationID		int
	DECLARE	@DomainID	int

	SELECT	@OrganizationID = c.ComputerOUID,
		@DomainID = o.DomainID
	FROM	Computer as c,
		Organization as o
	WHERE	@ComputerID = c.ComputerID
	  AND	c.ComputerOUID = o.OrganizationID

	CREATE TABLE #PolicyByOU (
		GUID binary(16),
		AccessGroupID int,
		OrganizationID int,
		NoOverride bit,
		EnabledForComputers bit,
		EnabledForUsers bit
	);
	IF @OrganizationID IS NOT NULL
	BEGIN
		EXEC PolicyIdentifyByOrganization @OrganizationID
		INSERT PolicyApplies (DomainID, TargetOUID, TargetTypeID, TargetID, GUID)
			SELECT	@DomainID as DomainID,
				@OrganizationID as OrganizationID,
				1 as TargetTypeID,
				@ComputerID as ComputerID,
				GUID
			FROM	#PolicyByOU as p
			WHERE EXISTS(		-- Authenticated Users is allowed
				SELECT * FROM Member
				WHERE	GroupID = p.AccessGroupID	-- The policy
				  AND	MemberMode = 1			-- allows
				  AND	TargetTypeID = 3		-- the group
				  AND	TargetID = 1			-- Authenticated Users
			) AND NOT EXISTS (	-- the record doesn't exist already
				SELECT * FROM PolicyApplies as pa
				WHERE	@DomainID = pa.DomainID
				  AND	@OrganizationID = TargetOUID
				  AND	1 = TargetTypeID
				  AND	@ComputerID = TargetID
				  AND	p.GUID  = pa.GUID
			)
	END
GO
/*
 * $Id: RemoteExecution.sql 92853 2009-07-14 00:32:01Z esholl $
 *
 * Description:
 *
 * SQL Script to add ManageSoft remote execution stored procedures.
 *
 * The steps performed by this script are:
 * 1. Add NetworkDeviceGetTargetedByPolicy procedure
 *
 * Protected by US patent 6,006,034; patents pending.
 * Copyright 2000-2003 ManageSoft Corporation. All rights reserved.
 * Reproduction, adaptation, or translation without prior permission
 * is prohibited.
 *
 */
 
-- Use ManageSoft database
-- USE ManageSoft
GO

-- Create NetworkDeviceGetTargetedByTask stored procedure
PRINT 'Creating procedure to query network devices targeted by a given task'
IF EXISTS(SELECT * FROM sysobjects WHERE xtype = 'P'
	AND name = 'NetworkDeviceGetTargetedByTask'
)
	DROP PROCEDURE NetworkDeviceGetTargetedByTask
GO
CREATE PROCEDURE NetworkDeviceGetTargetedByTask
	@guid BINARY(16)
AS
BEGIN
SELECT	*
FROM	NetworkDevice
WHERE	NetworkDevice.DeviceID IN
	(
		SELECT	aa.DeviceID
		FROM	ActionApplies as aa
			INNER JOIN Action as a
				ON aa.ActionUID = a.ActionUID
			INNER JOIN Task as t
				ON t.TaskID = a.TaskID
		WHERE t.TaskUID = @guid
	)

END
GO

-- Create NetworkDeviceGetTargetedByPolicy stored procedure
PRINT 'Creating procedure to query network devices targeted by a given policy'
IF EXISTS(SELECT * FROM sysobjects WHERE xtype = 'P'
	AND name = 'NetworkDeviceGetTargetedByPolicy'
)
	DROP PROCEDURE NetworkDeviceGetTargetedByPolicy
GO
CREATE PROCEDURE NetworkDeviceGetTargetedByPolicy
	@guid BINARY(16)
AS
BEGIN
SELECT	DeviceID,
	DuplicateID,
	ComputerID,
	DeviceName,
	DNSFullName,
	NTDomainName,
	IPAddress,
	IPSubnet,
	IPSubnetMask,
	PhysicalAddress,
	DeviceRole,
	OperatingSystem,
	OperatingSystemID,
	IsManaged,
	[Description],
	SystemDescription,
	SystemLocation,
	SystemContact,
	FirstDiscovered,
	LastUpdate,
	LastDataSourceName,
	LastDataSourceType
FROM	NetworkDevice
WHERE	NetworkDevice.ComputerID IN
	(
		SELECT	PolicyApplies.TargetID
		FROM	PolicyApplies
		WHERE	PolicyApplies.TargetTypeID = 1
		  AND	PolicyApplies.GUID = @guid
		UNION
		SELECT	Member.TargetID
		FROM	Member
		WHERE	TargetTypeID = 1
		  AND	Member.GroupID IN
			(
				SELECT	PolicyApplies.TargetID
				FROM	PolicyApplies
				WHERE	PolicyApplies.TargetTypeID = 3
				  AND	PolicyApplies.GUID = @guid
			)
	)

END
GO

-- Create NetworkDeviceGetTargetedByOU stored procedure
PRINT 'Creating procedure to query network devices within a given OU'
IF EXISTS(SELECT * FROM sysobjects WHERE xtype = 'P'
	AND name = 'NetworkDeviceGetTargetedByOU'
)
	DROP PROCEDURE NetworkDeviceGetTargetedByOU
GO
CREATE PROCEDURE NetworkDeviceGetTargetedByOU
	@oudn NVARCHAR(500)
AS
BEGIN
	SELECT	nde.*,
		ISNULL(nddbcnt.DiscoveredByCount, 0) AS DiscoveredByCount,
		ISNULL(nddbcnt.CanAdministerCount, 0) AS CanAdministerCount
	FROM	NetworkDeviceExtended AS nde
	INNER JOIN Computer AS c
		ON nde.ComputerID = c.ComputerID
	INNER JOIN Organization AS o
		ON c.ComputerOUID = o.OrganizationID
	INNER JOIN Domain AS d
		ON o.DomainID = d.OrganizationID
	LEFT OUTER JOIN
		(
			SELECT	nddb.DeviceID,
				COUNT(nddb.ServerUID) AS DiscoveredByCount,
				SUM(CONVERT(int, nddb.CanAdminister)) AS CanAdministerCount
			FROM	NetworkDeviceDiscoveredBy AS nddb
			GROUP BY nddb.DeviceID
		) AS nddbcnt ON nddbcnt.DeviceID = nde.DeviceID
	WHERE	RIGHT(o.RDN + ',' + d.DN, LEN(@oudn)) = @oudn

END
GO

-- Create TaskGetByActionMaxLastUpdate stored procedure
PRINT 'Creating procedure to query remote execution tasks, along with all the information necessary for the Task Browser'
IF EXISTS(SELECT * FROM sysobjects WHERE xtype = 'P'
	AND name = 'TaskExtendedGetAll'
)
	DROP PROCEDURE TaskExtendedGetAll
GO
CREATE PROCEDURE TaskExtendedGetAll
AS
BEGIN
	--Get the tasks along with the highest LastUpdate datetime of the associated Action
	SELECT *
	FROM TaskExtended
END
GO
/*
 * $Id: OracleAuditData.sql 92365 2010-10-29 08:00:00Z rparikh $
 *
 * DESCRIPTION: Stored Procedures
 *
 * Protected by US patent 6,006,034; patents pending.
 * Copyright 1990-2002 ManageSoft Corporation. All rights reserved.
 * Reproduction, adaptation, or translation without prior permission
 * is prohibited.
 */
 
--GetOracleLmsDetailInstanceDataByComputerIDInstanceName
IF EXISTS (
	SELECT * FROM sysobjects WHERE xtype = 'P'
	AND name = 'GetOracleLmsDetailInstanceDataByComputerIDInstanceName'
)
	DROP PROCEDURE GetOracleLmsDetailInstanceDataByComputerIDInstanceName
GO

CREATE PROCEDURE GetOracleLmsDetailInstanceDataByComputerIDInstanceName
	@ComputerID	int,
	@InstanceName	nvarchar(256)
AS
	with db as	(select sp.ParentServiceProviderID as dbID 
					from ServiceProvider sp, ServiceProviderName spn 
					where sp.ComputerID = @ComputerID and spn.Name = @InstanceName and ServiceProviderTypeID = 3
						and sp.ServiceProviderNameID = spn.ServiceProviderNameID),
		inst as	(select sp.ServiceProviderID as instID 
					from ServiceProvider sp, ServiceProviderName spn 
					where sp.ComputerID = @ComputerID and spn.Name = @InstanceName and ServiceProviderTypeID = 3
						and sp.ServiceProviderNameID = spn.ServiceProviderNameID)
	select created.Value as INSTALL_DATE, role.Value as DB_ROLE, banner.Value as BANNER, users.Value as USER_COUNT
	from 
		(select 1 as id, spv.Value 
			 from ServiceProviderProperty spp, ServiceProviderValue spv, db
			 where spp.ServiceProviderPropertyID = spv.ServiceProviderPropertyID 
				and spv.ServiceProviderID = db.dbID and spp.Property = 'role') role
	  left outer join
		(select 1 as id, spv.Value 
			 from ServiceProviderProperty spp, ServiceProviderValue spv, db
			 where spp.ServiceProviderPropertyID = spv.ServiceProviderPropertyID 
				and spv.ServiceProviderID = db.dbID and spp.Property = 'created') created
	   on role.id = created.id
	  left outer join
		(select 1 as id, spv.Value 
			 from ServiceProviderProperty spp, ServiceProviderValue spv, inst
			 where spp.ServiceProviderPropertyID = spv.ServiceProviderPropertyID 
				and spv.ServiceProviderID = inst.instID and spp.Property = 'banner') banner
	   on role.id = banner.id
	  left outer join
		(select 1 as id, COUNT(suo.ServiceUserID) as Value
			 from ServiceUser su, ServiceUserOracle suo, inst
			 where su.ServiceUserID = suo.ServiceUserID
					and su.ServiceProviderID = inst.instID
					and su.Name not in (
						'DBSNMP', 
						'JTI',
						'JTR',
						'JUNK_PS',
						'ODM',
						'ODM_MTR',
						'OSM',
						'OWAPUB',
						'PERFSTAT',
						'PM',
						'PORTAL30',
						'PORTAL30_DEMO',
						'PORTAL30_PUBLIC',
						'PORTAL30_SSO',
						'PORTAL30_SSO_PS',
						'PORTAL30_SSO_PUBLIC',
						'PTE',
						'PTG',
						'QS',
						'QS_ADM',
						'QS_CB',
						'QS_CBADM',
						'QS_CS',
						'QS_ES',
						'QS_OS',
						'QS_WS',
						'REPADMIN',
						'SCOTT',
						'SH',
						'SSOSDK',
						'TRACESVR',
						'WH',
						'WMSYS',
						'XDB',
						'ABM',
						'AD',
						'AD_MONITOR',
						'AHL',
						'AHM',
						'AK',
						'ALR',
						'AME',
						'AMF',
						'AMS',
						'AMV',
						'AMW',
						'AN',
						'AP',
						'APPLSYS',
						'APPLSYSPUB',
						'APPS',
						'APPS_MRC',
						'AR',
						'AS',
						'ASF',
						'ASG',
						'ASL',
						'ASN',
						'ASO',
						'ASP',
						'AST',
						'AU',
						'AX',
						'AZ',
						'BEN',
						'BIC',
						'BIE',
						'BIL',
						'BIM',
						'BIN',
						'BIS',
						'BIV',
						'BIX',
						'BIY',
						'BLC',
						'BNE',
						'BOM',
						'BSC',
						'CCT',
						'CDR',
						'CE',
						'CHV',
						'CLA',
						'CLE',
						'CLJ',
						'CLL',
						'CLN',
						'CN',
						'CPGC',
						'CRP',
						'CS',
						'CSC',
						'CSD',
						'CSE',
						'CSF',
						'CSI',
						'CSL',
						'CSM',
						'CSN',
						'CSP',
						'CSR',
						'CSS',
						'CST',
						'CTB',
						'CUA',
						'CUC',
						'CUE',
						'CUF',
						'CUG',
						'CUI',
						'CUN',
						'CUP',
						'CUR',
						'CUS',
						'CZ',
						'DDD',
						'DEM01',
						'DNA',
						'DOM',
						'DT',
						'DUMMY_GMO',
						'EAA',
						'EAM',
						'EC',
						'ECX',
						'EDR',
						'EGO',
						'EMS',
						'ENG',
						'ENI',
						'EVM',
						'FA',
						'FEM',
						'FF',
						'FII',
						'FLM',
						'FND',
						'FPA',
						'FPT',
						'FRM',
						'FTE',
						'FTP',
						'FUN',
						'FV',
						'GCS',
						'GHR',
						'GL',
						'GMA',
						'GMD',
						'GME',
						'GMF',
						'GMI',
						'GML',
						'GMO',
						'GMP',
						'GMS',
						'GMW',
						'GNI',
						'GR',
						'HCA',
						'HCC',
						'HCN',
						'HCP',
						'HCT',
						'HR',
						'HRI',
						'HXC',
						'HXT',
						'IA',
						'IAM',
						'IBA',
						'IBC',
						'IBE',
						'IBP',
						'IBT',
						'IBU',
						'IBW',
						'IBY',
						'ICX',
						'IEB',
						'IEC',
						'IEM',
						'IEO',
						'IEP',
						'IES',
						'IET',
						'IEU',
						'IEV',
						'IEX',
						'IGC',
						'IGF',
						'IGI',
						'IGS',
						'IGW',
						'IMC',
						'IMT',
						'INV',
						'IPA',
						'IPD',
						'IPM',
						'IRC',
						'ISC',
						'ISX',
						'IT_PERF',
						'ITA',
						'ITG',
						'IZU',
						'JA',
						'JE',
						'JG',
						'JL',
						'JMF',
						'JTF',
						'JTM',
						'JTS',
						'LNS',
						'ME',
						'MFG',
						'MIA',
						'MIV',
						'MQA',
						'MRP',
						'MSC',
						'MSD',
						'MSO',
						'MSR',
						'MST',
						'MWA',
						'OAM',
						'ODQ',
						'OE',
						'OFA',
						'OKB',
						'OKC',
						'OKC_REP_TXT_INDEX_OPTIMIZE',
						'OKC_REP_TXT_INDEX_SYNC',
						'OKE',
						'OKI',
						'OKL',
						'OKO',
						'OKP',
						'OKR',
						'OKS',
						'OKT',
						'OKX',
						'ONT',
						'OPI',
						'OTA',
						'OUC',
						'OZF',
						'OZP',
						'OZS',
						'PA',
						'PAY',
						'PBR',
						'PER',
						'PFT',
						'PJI',
						'PJM',
						'PMI',
						'PN',
						'PO',
						'POA',
						'POM',
						'PON',
						'POS',
						'PQH',
						'PQP',
						'PRP',
						'PSA',
						'PSB',
						'PSP',
						'PSR',
						'PTX',
						'PV',
						'QA',
						'QOT',
						'QP',
						'QRM',
						'RCM',
						'RG',
						'RHX',
						'RLA',
						'RLM',
						'RMG',
						'RRC',
						'RRS',
						'SHT',
						'SQLAP',
						'SQLGL',
						'SSP',
						'SYSADMIN',
						'TEST',
						'VEA',
						'VEH',
						'WIP',
						'WMA',
						'WMS',
						'WPS',
						'WSH',
						'WSM',
						'XDO',
						'XDP',
						'XLA',
						'XLE',
						'XNA',
						'XNB',
						'XNC',
						'XNI',
						'XNM',
						'XNP',
						'XNS',
						'XNT',
						'XTR',
						'ZFA',
						'ZPB',
						'ZSA',
						'ZX',
						'CTSYS',
						'MDSYS',
						'OLAPSVR',
						'ORDPLUGINS',
						'OLAPDBA',
						'OLAPSYS',
						'ORDSYS',
						'OUTLN',
						'AURORA$JIS$UTILITY$',
						'AURORA$ORB$UNAUTHENTICATED',
						'DCM',
						'INTERNET_APPSERVER_REGISTRY',
						'IP',
						'OCA',
						'ORAOCA_PUBLIC',
						'OSE$HTTP$ADMIN',
						'OWA_MGR',
						'UDDISYS',
						'WFADMIN',
						'WIRELESS',
						'WK_PROXY',
						'WKSYS',
						'WK_Test',
						'CLKRT',
						'BLEWIS',
						'CDOUGLAS',
						'KWALKER',
						'SPIERSON',
						'DISCOVERER5',
						'DSGATEWAY',
						'DSSYS',
						'ODS',
						'ODSCOMMON',
						'ORASSO',
						'ORASSO_DS',
						'ORASSO_PA',
						'ORASSO_PS',
						'ORASSO_PUBLIC',
						'PORTAL',
						'PORTAL_APP',
						'PORTAL_DEMO',
						'PORTAL_PUBLIC'
						)
					) users
	   on role.id = users.id
GO

--GetOracleLmsComputerDataByComputerID
IF EXISTS (
	SELECT * FROM sysobjects WHERE xtype = 'P'
	AND name = 'GetOracleLmsComputerDataByComputerID'
)
	DROP PROCEDURE GetOracleLmsComputerDataByComputerID
GO

CREATE PROCEDURE GetOracleLmsComputerDataByComputerID
	@ComputerID	int
AS
	select cs.Manufacturer as SERVER_MANUFACTURER, cs.Model as SERVER_MODEL, cs.NumberOfProcessors as SOCKETS_POPULATED_PHYS,
			copsys.Caption as OPERATING_SYSTEM, cp.Name as PROCESSOR_IDENTIFIER , cp.MaxClockSpeed as PROCESSOR_SPEED, 
			pt.PartitionType as PARTITIONING_METHOD, sum(cp.NumberOfCores) as TOTAL_PHYSICAL_CORES, sum(cp.NumberOfCores) as TOTAL_LOGICAL_CORES
	from ComputerSystem cs
	  left outer join ComputerOperatingSystem copsys
	   on cs.ComputerID = copsys.ComputerID
	  left outer join ComputerProcessor cp
	   on cs.ComputerID = cp.ComputerID
	  left outer join
		(select 'VMware' as PartitionType, ComputerID from ComputerSystem where Manufacturer like 'vmware%') pt
	   on cs.ComputerID = pt.ComputerID
	where cs.ComputerID = @ComputerID
	group by cs.Manufacturer, cs.Model, cs.NumberOfProcessors, copsys.Caption, 
			cp.Name, cp.MaxClockSpeed, pt.PartitionType
GO


--GetOracleLmsOverviewDataByComputerIDInstanceName
IF EXISTS (
	SELECT * FROM sysobjects WHERE xtype = 'P'
	AND name = 'GetOracleLmsOverviewDataByComputerIDInstanceName'
)
	DROP PROCEDURE GetOracleLmsOverviewDataByComputerIDInstanceName
GO

CREATE PROCEDURE GetOracleLmsOverviewDataByComputerIDInstanceName
	@ComputerID	int,
	@InstanceName	nvarchar(256)
AS
	select vered.Version as "Database Version", vered.edition as "Database Edition",
			sessionsmax.Value as "Sessions Maximum", sessionshighwater.Value as "Sessions Highwater"
	from 
		(select 1 as id, version, edition 
		 from ServiceComponent sc 
		 where ServiceComponentID in 
			(select top 1 ServiceComponentID 
			 from ServiceProviderComponent 
			 where ServiceProviderID in
				(select sp.ParentServiceProviderID as dbID 
				 from ServiceProvider sp, ServiceProviderName spn 
				 where sp.ComputerID = @ComputerID and spn.Name = @InstanceName and ServiceProviderTypeID = 3
					and sp.ServiceProviderNameID = spn.ServiceProviderNameID))) vered
	  left outer join
		(select 1 as id, spv.Value 
		 from ServiceProviderProperty spp, ServiceProviderValue spv,
			(select sp.ParentServiceProviderID as dbID 
			 from ServiceProvider sp, ServiceProviderName spn 
			 where sp.ComputerID = @ComputerID and spn.Name = @InstanceName and ServiceProviderTypeID = 3
				and sp.ServiceProviderNameID = spn.ServiceProviderNameID) db
		 where spp.ServiceProviderPropertyID = spv.ServiceProviderPropertyID
			and spv.ServiceProviderID = db.dbID and spp.Property = 'sessionsmax') sessionsmax
	   on vered.id = sessionsmax.id
	  left outer join
		(select 1 as id, spv.Value
		 from ServiceProviderProperty spp, ServiceProviderValue spv,
			(select sp.ParentServiceProviderID as dbID 
			 from ServiceProvider sp, ServiceProviderName spn 
			 where sp.ComputerID = @ComputerID and spn.Name = @InstanceName and ServiceProviderTypeID = 3
				and sp.ServiceProviderNameID = spn.ServiceProviderNameID) db
		 where spp.ServiceProviderPropertyID = spv.ServiceProviderPropertyID
			and spv.ServiceProviderID = db.dbID and spp.Property = 'sessionshighwater') sessionshighwater
	   on vered.id = sessionshighwater.id
GO


--GetOracleOptionsInstalledByComputerIDInstanceName
IF EXISTS (
	SELECT * FROM sysobjects WHERE xtype = 'P'
	AND name = 'GetOracleOptionsInstalledByComputerIDInstanceName'
)
	DROP PROCEDURE GetOracleOptionsInstalledByComputerIDInstanceName
GO

CREATE PROCEDURE GetOracleOptionsInstalledByComputerIDInstanceName
	@ComputerID	int,
	@InstanceName	nvarchar(256)
AS
	select sc.Name as "Options Installed" 
	from ServiceProviderComponent spc, ServiceComponent sc
	where spc.ServiceProviderID in
		(select sp.ServiceProviderID as instID 
		 from ServiceProvider sp, ServiceProviderName spn 
		 where sp.ComputerID = @ComputerID and spn.Name = @InstanceName and ServiceProviderTypeID = 3
			and sp.ServiceProviderNameID = spn.ServiceProviderNameID)
		and spc.ServiceComponentID = sc.ServiceComponentID
GO


--GetOracleOptionsUsedByComputerIDInstanceName
IF EXISTS (
	SELECT * FROM sysobjects WHERE xtype = 'P'
	AND name = 'GetOracleOptionsUsedByComputerIDInstanceName'
)
	DROP PROCEDURE GetOracleOptionsUsedByComputerIDInstanceName
GO

CREATE PROCEDURE GetOracleOptionsUsedByComputerIDInstanceName
	@ComputerID	int,
	@InstanceName	nvarchar(256)
AS
	select sc.Name as "Options Used" 
	from ServiceProviderComponent spc, ServiceComponent sc, 
		ServiceProviderComponentProperty spcp, ServiceProviderComponentValue spcv
	where spc.ServiceProviderID in
		(select sp.ServiceProviderID as instID 
		 from ServiceProvider sp, ServiceProviderName spn 
		 where sp.ComputerID = @ComputerID and spn.Name = @InstanceName and ServiceProviderTypeID = 3
			and sp.ServiceProviderNameID = spn.ServiceProviderNameID)
		and spc.ServiceComponentID = sc.ServiceComponentID
		and sc.ServiceComponentID = spcv.ServiceComponentID
		and spcp.ServiceProviderComponentPropertyID = spcv.ServiceProviderComponentPropertyID
		and spc.ServiceProviderID = spcv.ServiceProviderID
		and spcp.Property = 'currentlyused' and spcv.Value = 'true' 
GO
/*
 * $Id: Rights.sql 93226 2009-08-06 05:33:52Z rlowery $
 *
 * Description:
 *
 * SQL Script to add ManageSoft remote execution stored procedures.
 *
 * The steps performed by this script are:
 * 1. Add NetworkDeviceGetTargetedByPolicy procedure
 *
 * Protected by US patent 6,006,034; patents pending.
 * Copyright 2000-2003 ManageSoft Corporation. All rights reserved.
 * Reproduction, adaptation, or translation without prior permission
 * is prohibited.
 *
 */
 
-- Use ManageSoft database
-- USE ManageSoft
GO

-- Create RightSetAdminRightsByGroupID stored procedure
PRINT 'Creating procedure to assign admin rights to the specified group'
IF EXISTS(SELECT * FROM sysobjects WHERE xtype = 'P'
		AND name = 'RightSetAdminRightsByGroupID')
	DROP PROCEDURE RightSetAdminRightsByGroupID
GO
CREATE PROCEDURE RightSetAdminRightsByGroupID
	@GroupId	int
AS
BEGIN
	--Note when adding new Rights, the DELETE statement below should also be updated to reset deny rights
	IF (NOT EXISTS(select * from [Right] where GroupID = @GroupId AND ResourceID = 21))
	BEGIN
		INSERT INTO [Right] (GroupID, ResourceID, ActionClassID, Denied, [Value])
		VALUES (@GroupId, 21, 2, 0, 0)
	END
	IF (NOT EXISTS(select * from [Right] where GroupID = @GroupId AND ResourceID = 3))
	BEGIN
		INSERT INTO [Right] (GroupID, ResourceID, ActionClassID, Denied, [Value])
		VALUES (@GroupId, 3, 2, 0, 0)
	END
	IF (NOT EXISTS(select * from [Right] where GroupID = @GroupId AND ResourceID = 15))
	BEGIN
		INSERT INTO [Right] (GroupID, ResourceID, ActionClassID, Denied, [Value])
		VALUES (@GroupId, 15, 2, 0, 0)
	END
	IF (NOT EXISTS(select * from [Right] where GroupID = @GroupId AND ResourceID = 4))
	BEGIN
		INSERT INTO [Right] (GroupID, ResourceID, ActionClassID, Denied, [Value])
		VALUES (@GroupId, 4, 1, 0, 0)
	END
	IF (NOT EXISTS(select * from [Right] where GroupID = @GroupId AND ResourceID = 16))
	BEGIN
		INSERT INTO [Right] (GroupID, ResourceID, ActionClassID, Denied, [Value])
		VALUES (@GroupId, 16, 1, 0, 0)
	END
	IF (NOT EXISTS(select * from [Right] where GroupID = @GroupId AND ResourceID = 12))
	BEGIN
		INSERT INTO [Right] (GroupID, ResourceID, ActionClassID, Denied, [Value])
		VALUES (@GroupId, 12, 1, 0, 0)
	END
	IF (NOT EXISTS(select * from [Right] where GroupID = @GroupId AND ResourceID = 14))
	BEGIN
		INSERT INTO [Right] (GroupID, ResourceID, ActionClassID, Denied, [Value])
		VALUES (@GroupId, 14, 1, 0, 0)
	END
	IF (NOT EXISTS(select * from [Right] where GroupID = @GroupId AND ResourceID = 24))
	BEGIN
		INSERT INTO [Right] (GroupID, ResourceID, ActionClassID, Denied, [Value])
		VALUES (@GroupId, 24, 1, 0, 0)
	END
	IF (NOT EXISTS(select * from [Right] where GroupID = @GroupId AND ResourceID = 6))
	BEGIN
		INSERT INTO [Right] (GroupID, ResourceID, ActionClassID, Denied, [Value])
		VALUES (@GroupId, 6, 1, 0, 0)
	END
	IF (NOT EXISTS(select * from [Right] where GroupID = @GroupId AND ResourceID = 22))
	BEGIN
		INSERT INTO [Right] (GroupID, ResourceID, ActionClassID, Denied, [Value])
		VALUES (@GroupId, 22, 1, 0, 0)
	END
	IF (NOT EXISTS(select * from [Right] where GroupID = @GroupId AND ResourceID = 23))
	BEGIN
		INSERT INTO [Right] (GroupID, ResourceID, ActionClassID, Denied, [Value])
		VALUES (@GroupId, 23, 1, 0, 0)
	END
	IF (NOT EXISTS(select * from [Right] where GroupID = @GroupId AND ResourceID = 25))
	BEGIN
		INSERT INTO [Right] (GroupID, ResourceID, ActionClassID, Denied, [Value])
		VALUES (@GroupId, 25, 1, 0, 0)
	END
	
	DELETE [Right]
	WHERE ResourceID IN (4, 6, 12, 14, 16, 22, 23, 24, 25)
	AND Denied = 1
	AND ActionClassID = 1
	AND GroupID = @GroupID

	DELETE [Right]
	WHERE ResourceID IN (3, 15, 21)
	AND Denied = 1
	AND ActionClassID = 2
	AND GroupID = @GroupID
END
GO

-- Create RightSetReportRightsByGroupID stored procedure
PRINT 'Creating procedure to assign report viewing rights to the specified group'
IF EXISTS(SELECT * FROM sysobjects WHERE xtype = 'P'
		AND name = 'RightSetReportRightsByGroupID')
	DROP PROCEDURE RightSetReportRightsByGroupID
GO
CREATE PROCEDURE RightSetReportRightsByGroupID
	@GroupId	int
AS
	--Note when adding new Rights, the DELETE statement below should also be updated to reset deny rights
	IF (NOT EXISTS(select * from [Right] where GroupID = @GroupId AND ResourceID = 4))
	BEGIN
		INSERT INTO [Right] (GroupID, ResourceID, ActionClassID, Denied, [Value])
		VALUES (@GroupId, 4, 1, 0, 0)
	END
	IF (NOT EXISTS(select * from [Right] where GroupID = @GroupId AND ResourceID = 16))
	BEGIN
		INSERT INTO [Right] (GroupID, ResourceID, ActionClassID, Denied, [Value])
		VALUES (@GroupId, 16, 1, 0, 0)
	END
	IF (NOT EXISTS(select * from [Right] where GroupID = @GroupId AND ResourceID = 12))
	BEGIN
		INSERT INTO [Right] (GroupID, ResourceID, ActionClassID, Denied, [Value])
		VALUES (@GroupId, 12, 1, 0, 0)
	END
	IF (NOT EXISTS(select * from [Right] where GroupID = @GroupId AND ResourceID = 14))
	BEGIN
		INSERT INTO [Right] (GroupID, ResourceID, ActionClassID, Denied, [Value])
		VALUES (@GroupId, 14, 1, 0, 0)
	END
	IF (NOT EXISTS(select * from [Right] where GroupID = @GroupId AND ResourceID = 24))
	BEGIN
		INSERT INTO [Right] (GroupID, ResourceID, ActionClassID, Denied, [Value])
		VALUES (@GroupId, 24, 1, 0, 0)
	END
	IF (NOT EXISTS(select * from [Right] where GroupID = @GroupId AND ResourceID = 6))
	BEGIN
		INSERT INTO [Right] (GroupID, ResourceID, ActionClassID, Denied, [Value])
		VALUES (@GroupId, 6, 1, 0, 0)
	END
	IF (NOT EXISTS(select * from [Right] where GroupID = @GroupId AND ResourceID = 22))
	BEGIN
		INSERT INTO [Right] (GroupID, ResourceID, ActionClassID, Denied, [Value])
		VALUES (@GroupId, 22, 1, 0, 0)
	END
	IF (NOT EXISTS(select * from [Right] where GroupID = @GroupId AND ResourceID = 23))
	BEGIN
		INSERT INTO [Right] (GroupID, ResourceID, ActionClassID, Denied, [Value])
		VALUES (@GroupId, 23, 1, 0, 0)
	END
	IF (NOT EXISTS(select * from [Right] where GroupID = @GroupId AND ResourceID = 25))
	BEGIN
		INSERT INTO [Right] (GroupID, ResourceID, ActionClassID, Denied, [Value])
		VALUES (@GroupId, 25, 1, 0, 0)
	END

	DELETE [Right]
	WHERE ResourceID IN (4, 6, 12, 14, 16, 22, 23, 24, 25)
	AND Denied = 1
	AND ActionClassID = 1
	AND GroupID = @GroupID
GO
