CREATE TABLE [dbo].[User](
[UserID] [int] IDENTITY(1,1) NOT NULL,
[UserName] [varchar](50) NOT NULL,
[Password] [varchar](50) NOT NULL,
CONSTRAINT [PK_User] PRIMARY KEY CLUSTERED
(
[UserID] ASC
) ON [PRIMARY]
CREATE TABLE [dbo].[Module](
[ModuleID] [int] NOT NULL,
[ModuleName] [nvarchar](50) NOT NULL,
CONSTRAINT [PK_Module] PRIMARY KEY CLUSTERED
(
[ModuleID] ASC
) ON [PRIMARY]
CREATE TABLE [dbo].[Role](
[RoleID] [int] NOT NULL,
[RoleName] [nvarchar](50) NOT NULL,
CONSTRAINT [PK_Role] PRIMARY KEY CLUSTERED
(
[RoleID] ASC
) ON [PRIMARY]
CREATE TABLE [dbo].[UserRoleSetting](
[UserID] [int] NOT NULL, /* FK to User table */
[ModuleID] [int] NOT NULL, /* FK to Module table */
[RoleID] [int] NOT NULL, /* FK to Role table */
CONSTRAINT [PK_UserRoleSetting] PRIMARY KEY CLUSTERED
(
[UserID] ASC,
[ModuleID] ASC
) ON [PRIMARY]
GO
I have a schema like this to define the users have different roles under different modules. I know if UserRoleSetting table is just a simple many to many relationship table, it is easy to define. But that table actually contains relationship from 3 different tables, so what might be the correct syntax to load user role settings into user object?
Thanks
Hardy
What you would like to map is a three-way many-to-many.
You can't define it directly. You instead create a separate entity UserRoleSetting and map it using: one-to-manys in User, Module, Role and many-to-one in UserRoleSetting. In FluentNHibernate it translates into HasMany() and References() respectively.
You can omit one side of the mapping of each connection if bi-directionality is not needed.
Does that solve your problem?
Related
I am using Microsoft SQL Server 2014 Express as a database server.
I have the following two tables between which I want to create PK-FK relationship.
CREATE TABLE [dbo].[Account]
(
[ID] [int] IDENTITY(1,1) NOT NULL,
[ACCOUNTNAME] [nvarchar](max) NOT NULL,
[ACCOUNTTYPE] [int] NOT NULL,
[CREATE_TIMESTAMP] [datetime] NOT NULL,
[LAST_EDIT_TIMESTAMP] [datetime] NOT NULL,
[OPENING_BALANCE] [decimal](18, 2) NOT NULL DEFAULT ((0)),
[OPENING_BALANCE_TYPE] [nvarchar](50) NULL,
CONSTRAINT [PK_dbo.Account]
PRIMARY KEY CLUSTERED ([ID] ASC)
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
CREATE TABLE [dbo].[Voucher]
(
[ID] [int] IDENTITY(1,1) NOT NULL,
[VOUCHERTYPE] [nvarchar](50) NOT NULL,
[VOUCHERNO] [int] NOT NULL,
[DATE] [datetime] NOT NULL,
[AMOUNT] [decimal](18, 2) NOT NULL,
[DRPARTY] [int] NOT NULL,
[CRPARTY] [int] NOT NULL,
[DETAILS] [nvarchar](50) NOT NULL,
[ORIGIN] [nvarchar](50) NULL,
[ORIGINID] [int] NOT NULL,
[ORIGINDETAILS] [nvarchar](max) NULL,
[CREATE_TIMESTAMP] [datetime] NOT NULL DEFAULT ('1900-01-01T00:00:00.000'),
[LAST_EDIT_TIMESTAMP] [datetime] NOT NULL DEFAULT ('1900-01-01T00:00:00.000'),
[TRANSACTION_TYPE] [nvarchar](50) NULL,
CONSTRAINT [PK_dbo.Voucher]
PRIMARY KEY CLUSTERED ([ID] ASC)
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
GO
This is the error I am getting when creating FK relationship via Microsoft SQL Server Management Studio. Both tables are empty.
'Account' table saved successfully
'Voucher' table - Unable to create relationship 'FK_Voucher_Account1'. The ALTER TABLE statement conflicted with the FOREIGN KEY constraint "FK_Voucher_Account1". The conflict occurred in database "SKUMAR", table "dbo.Account", column 'ID'
I want to create a relation between Account.ID -> Voucher.DRPARTY and Account.ID -> Voucher.CRPARTY but I am unable to create second FK relationship.
May I know how to solve this?
There is a possibility of conflicted foreign key error because of data mismatch between Voucher(CRPARTY) column and Account(Id) column. Rows available in CRPARTY table must be in Account table.
Verify using below query.
SELECT * FROM Voucher WHERE CRPARTY NOT IN (SELECT Id FROM Account);
I was able to create 2 FKs to 1 PK. http://rextester.com/WMAT80057
You can delete the FK relationships between your tables and use this script to create them. Hopefully, your tables do not have non matching data.
ALTER TABLE [dbo]. [Voucher] WITH CHECK ADD CONSTRAINT [FK_ACCOUNT_ID_VOUCHER_DRPARTY] FOREIGN KEY ([DRPARTY]) REFERENCES [dbo]. [Account]([ID])
GO
ALTER TABLE [dbo]. [Voucher] CHECK CONSTRAINT [FK_ACCOUNT_ID_VOUCHER_DRPARTY]
GO
ALTER TABLE [dbo]. [Voucher] WITH CHECK ADD CONSTRAINT [FK_ACCOUNT_ID_VOUCHER_CRPARTY] FOREIGN KEY ([CRPARTY]) REFERENCES [dbo]. [Account]([ID])
GO
ALTER TABLE [dbo]. [Voucher] CHECK CONSTRAINT [FK_ACCOUNT_ID_VOUCHER_CRPARTY]
GO
From my original database, I made changes to some tables with columns in the table, I want to merge them into a single database. New database just add some table and old table add some columns.
How to merge multiple database into one database?
SQL example:
CREATE TABLE [dbo].[Item]
(
[ItemID] [nchar](10) NOT NULL,
[Money] [bigint] NOT NULL,
[ItemName] [bigint] NOT NULL,
[MoneyType] [bigint] NOT NULL,
CONSTRAINT [PK_Item]
PRIMARY KEY CLUSTERED ([ItemID] ASC) ON [PRIMARY]
) ON [PRIMARY]
GO
CREATE TABLE [dbo].[Account]
(
[Index] [int] IDENTITY(1,1) NOT NULL,
[AccountID] [nchar](10) NOT NULL,
[AccountName] [int] NOT NULL,
[ItemList] [int] NOT NULL,
) ON [PRIMARY]
GO
CREATE TABLE [dbo].[Money]
(
[AccountID] [nchar](10) NOT NULL,
[Money] [bigint] NOT NULL,
[MoneyType] [bigint] NOT NULL,
CONSTRAINT [PK_Money]
PRIMARY KEY CLUSTERED ([AccountID] ASC) ON [PRIMARY]
) ON [PRIMARY]
GO
-> Nick.McDermaid: use the schema compare tool in Visual Studio (various free editions) which will create a change script!
This will combine them onto DBCombined.Account if the Account table does NOT exist yet: the SELECT INTO code creates the target table. You would then need to add any indexes from the original tables. Also, "SELECT *" should really be broken out, listing each field, because if you have an ID field it will contain duplicates. Better to leave ID off during the insert and then go back and add an identity column.
USE DBCombined
GO
SELECT *
INTO Account
FROM (
SELECT *
FROM DB1.dbo.Account
UNION ALL
SELECT *
FROM DB2.dbo.Account
) Acct
I am working on a project where I need to extract the data from excel sheet to SQL Server
, well that bit have done successfully. Now my problem is that for a particular column
called product size, I want to update current table based on product size in other table, I am really very confused , please help me out
Please find the table structure
CREATE TABLE [dbo].[T_Product](
[ProductID] [int] IDENTITY(1,1) NOT NULL,
[PartNo] [nvarchar](255) NULL,
[CategoryID] [int] NULL,
[MaterialID] [float] NULL,
[WireformID] [float] NULL,
[ProductName] [nvarchar](50) NULL,
[ProductSize] [nvarchar](50) NULL,
[ProductLength] [varchar](20) NULL,
[ProductActive] [bit] NULL,
[ProductImage] [varchar](60) NULL
) ON [PRIMARY]
CREATE TABLE [dbo].[T_ProductSize](
[Code] [int] IDENTITY(1,1) NOT NULL,
[ProductSize] [nvarchar](50) NULL,
[Length] [nchar](20) NULL
) ON [PRIMARY]
GO
OK, so ignore the previous answer, I got the wrong end of the stick!!
You want something like this I think:
UPDATE T_Product
SET [ProductLength] = ps.[Length]
FROM T_Product p
INNER JOIN T_ProductSize ps
ON p.[ProductSize] = ps.[ProductSize]
That will take the Length value from T_ProductSize and place it in T_Product.ProductLength based on the value of T_Product.ProductSize
You mention a foreign key but you haven't included a definition for it. Is it between the two tables in your example? If so, which columns make the key? Is product size the key? If so, then your question doesn't make a lot of sense as the value will be the same in both tables.
Is it possible that you mean the product size is to be stored in a separate table and not in the T_Product table? In that case then instead of ProductSize in T_Product you will want the code from the T_ProductSize table (can I also suggest that instead of 'code' you call it 'ProductSizeCode' or better yet 'ProductSizeId' or similar? having columns simply called code can be very confusing as you have no simple way of know what table that value is in). Also, you should always create a primary key on each table: You cannot have a foreign key without one. They don't have to be clustered, that will depend upon hwo your search the table, but I am using a clustered PK for this example. That would give you something like this:
CREATE TABLE [dbo].[T_Product](
[ProductID] [int] IDENTITY(1,1) NOT NULL,
[PartNo] [nvarchar](255) NULL,
[CategoryID] [int] NULL,
[MaterialID] [float] NULL,
[WireformID] [float] NULL,
[ProductName] [nvarchar](50) NULL,
[ProductSizeId] [int] NOT NULL,
[ProductLength] [varchar](20) NULL,
[ProductActive] [bit] NULL,
[ProductImage] [varchar](60) NULL
CONSTRAINT [PK_T_Product] PRIMARY KEY CLUSTERED
(
[ProductID] ASC
) ON [PRIMARY]
) ON [PRIMARY]
GO
CREATE TABLE [dbo].[T_ProductSize](
[ProductSizeId] [int] IDENTITY(1,1) NOT NULL,
[ProductSize] [nvarchar](50) NULL,
[Length] [nchar](20) NULL
CONSTRAINT [PK_T_ProductSize] PRIMARY KEY CLUSTERED
(
[ProductSizeId] ASC
) ON [PRIMARY]
) ON [PRIMARY]
GO
--Now add your foreign key to T_Product.
ALTER TABLE [T_Product] WITH NOCHECK ADD CONSTRAINT [FK_Product_ProductSize] FOREIGN KEY([ProductSizeId])
REFERENCES [T_ProductSize] ([ProductSizeId])
GO
ALTER TABLE [T_Product] CHECK CONSTRAINT [FK_Product_ProductSize]
GO
Now, to retrieve your product along with the product size use something like this:
SELECT p.[ProductID], p.[PartNo], p.[CategoryID], p.[MaterialID], p.[WireformID], p.[ProductName],
ps.[ProductSize], ps.[Length], p.[ProductLength], p.[ProductActive], p.[ProductImage]
FROM [T_Product] p
INNER JOIN [T_ProductSize] ps
ON ps.[ProductSizeId] = p.[ProductSizeId]
If I have understood you correctly, then this is what I think you're after. If not, then have another go at explaining what it is you need and I'll try again.
Try this...
UPDATE t2
SET t2.ProductLength = t1.Length
FROM dbo.T_ProductSize t1
INNER JOIN dbo.T_Product t2 ON t1.ProductSize = t2.ProductSize
I'm having some trouble figuring out the correct syntax for mapping a many-to-many relationship with FluentNHibernate. I've looked at several of the other questions here on SO and other places, but haven't seen anything with, specifically, the same table structure. Hoping someone that knows more than I do about FNH can help me figure this out. Here's my table structures:
CREATE TABLE [dbo].[WorkItems](
[Id] [bigint] IDENTITY(1,1) NOT NULL,
[CategoryId] [bigint] NOT NULL,
[DateTime] [datetime] NOT NULL,
[Details] [nvarchar](2000) NULL,
[Duration] [int] NOT NULL,
[DurationInterval] [nvarchar](10) NOT NULL,
[Summary] [nvarchar](150) NOT NULL,
[UserId] [bigint] NOT NULL,
PRIMARY KEY CLUSTERED ([Id] ASC)
CREATE TABLE [dbo].[Tags](
[Id] [bigint] IDENTITY(1,1) NOT NULL,
[Name] [nvarchar](50) NOT NULL,
PRIMARY KEY CLUSTERED ([Id] ASC)
CREATE TABLE [dbo].[TagWorkItems](
[TagId] [bigint] NOT NULL,
[WorkItemId] [bigint] NOT NULL,
CONSTRAINT [TagId_WorkItemId_PK] PRIMARY KEY CLUSTERED
(
[TagId] ASC,
[WorkItemId] ASC
)
TagId and WorkItemId in the TagWorkItems table are both foreign keys back to the parent tables. It's a pretty straight-forward join table setup for a m2m relationship. My Tag class has a property of type ICollection, and my WorkItem class has a property of ICollection. I can't seem to figure out how to setup the Mappings for those properties. Any advice would be greatly appreciated. Thanks.
Here's an example of what a WorkItem mapping might say; the readonly bit depends on how you're going to maintain the relationship:
HasManyToMany(x => x.Tags)
.Table("TagWorkItems")
.ParentKeyColumn("WorkItemId")
.ChildKeyColumn("TagId")
.AsSet()
.ReadOnly();
SQL Server 2005:
I have a SiteVisit row which contains information about a users visit, for instance HttpRefer, whether or not they placed an order, browser, etc.
Currently for reporting I am joining this table with SiteEvent which contains information about each 'section' visited. This then produces a view which shows statistics about how many sections each user visited. Obviously this is not a sustainable way to do this and now I'm doing some refactoring.
I'd like to move the SectionsVisited column from my View to an actual column in SiteVisit. I'd then update it everytime a user went to that session.
Now my actual question:
What kind of considerations do I need to take into account when updating a row many times per session. Obviously I have an index on the row (currently indexed by a GUID to prevent most malicious tampering).
I just want to know what non-obvious things I should do (if any). Are there any specific things I should do to optimize the table or will SQL server 2005 pretty much take care of itself
NB: it is a flash site so please dont just recommend a tracking tool. I want to do some
'crazy' datamining and have developed the tracking as such. This is primarily intended to be a database question not a question about 'how to track'.
Requested table definition:
USE [RazorSite]
GO
/****** Object: Table [dbo].[SiteVisit] Script Date: 10/29/2008 14:35:56 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
SET ANSI_PADDING ON
GO
CREATE TABLE [dbo].[SiteVisit](
[SiteVisitId] [int] IDENTITY(1,1) NOT NULL,
[SiteUserId] [int] NULL,
[ClientGUID] [uniqueidentifier] ROWGUIDCOL NULL CONSTRAINT [DF_SiteVisit_ClientGUID] DEFAULT (newid()),
[ServerGUID] [uniqueidentifier] NULL,
[UserGUID] [uniqueidentifier] NULL,
[SiteId] [int] NOT NULL,
[EntryURL] [varchar](100) NULL,
[CampaignId] [varchar](50) NULL,
[Date] [datetime] NOT NULL,
[Cookie] [varchar](50) NULL,
[UserAgent] [varchar](255) NULL,
[Platform] [int] NULL,
[Referer] [varchar](255) NULL,
[RegisteredReferer] [int] NULL,
[FlashVersion] [varchar](20) NULL,
[SiteURL] [varchar](100) NULL,
[Email] [varchar](50) NULL,
[FlexSWZVersion] [varchar](20) NULL,
[HostAddress] [varchar](20) NULL,
[HostName] [varchar](100) NULL,
[InitialStageSize] [varchar](20) NULL,
[OrderId] [varchar](50) NULL,
[ScreenResolution] [varchar](50) NULL,
[TotalTimeOnSite] [int] NULL,
[CumulativeVisitCount] [int] NULL CONSTRAINT [DF_SiteVisit_CumulativeVisitCount] DEFAULT ((0)),
[ContentActivatedTime] [int] NULL CONSTRAINT [DF_SiteVisit_ContentActivatedTime] DEFAULT ((0)),
[ContentCompleteTime] [int] NULL,
[MasterVersion] [int] NULL CONSTRAINT [DF_SiteVisit_MasterVersion] DEFAULT ((0)),
CONSTRAINT [PK_SiteVisit] PRIMARY KEY CLUSTERED
(
[SiteVisitId] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
SET ANSI_PADDING OFF
GO
ALTER TABLE [dbo].[SiteVisit] WITH CHECK ADD CONSTRAINT [FK_SiteVisit_Platform] FOREIGN KEY([Platform])
REFERENCES [dbo].[Platform] ([PlatformId])
GO
ALTER TABLE [dbo].[SiteVisit] CHECK CONSTRAINT [FK_SiteVisit_Platform]
GO
ALTER TABLE [dbo].[SiteVisit] WITH CHECK ADD CONSTRAINT [FK_SiteVisit_Site] FOREIGN KEY([SiteId])
REFERENCES [dbo].[Site] ([SiteId])
GO
ALTER TABLE [dbo].[SiteVisit] CHECK CONSTRAINT [FK_SiteVisit_Site]
GO
ALTER TABLE [dbo].[SiteVisit] WITH CHECK ADD CONSTRAINT [FK_SiteVisit_SiteUser] FOREIGN KEY([SiteUserId])
REFERENCES [dbo].[SiteUser] ([SiteUserId])
GO
ALTER TABLE [dbo].[SiteVisit] CHECK CONSTRAINT [FK_SiteVisit_SiteUser]
Current indexes:
IX_CampaignId - non unique, non clustered
IX_ClientGUID - Unique, non clustered <-- this is how a user is identified for updates
IX_UserGUID - non unique, non clustered
PK_SiteVisit - (SiteVisitId column) - clustered
The best suggestion that I can give is: keep the table small.
How? Have one table that contains all "live" data, i.e. active sessions. When a session expires : move the data out to an "archive" table or even another database server to do your mining.
Have only very few indexes on the "live" table (session id). You can have all the indexes you want on the "archive" table for faster data retreival.