Please start any new threads on our new
site at https://forums.sqlteam.com. We've got lots of great SQL Server
experts to answer whatever question you can come up with.
| Author |
Topic |
|
shapper
Constraint Violating Yak Guru
450 Posts |
Posted - 2007-09-10 : 09:37:34
|
| Hello,I have 3 tables with their columns: [Articles] > ArticleId, ArticleText [Categories] > CategoryId, CategoryText [CategoriesInArticles] > ArticleId, CategoryIdI created a stored procedure that has the following inputs: ArticleId, ArticleCategoriesArticleCategories is of type NVARCHAR(Max) and has categories in CSV format: "Category A, Category B, Category C"I have a function, CSVTable, which I took from SQLTeam.com that creates a table with all the categories.I need to make a kind of synchronization:> Update all categories for the given ArticleId. If any Category is no longer associated with any ArticleId (In CategoriesInArticles) then remove it from table Categories.I created the following code: INSERT INTO CategoriesInArticles(CategoryId, ArticleId)SELECT c.CategoryId, @ArticleIdFROM Categories c INNER JOIN CSVTable(@ArticleCategories) acON c.CategoryText = ac.StringLEFT JOIN CategoriesInArticles ciaON c.CategoryId = cia.CategoryIdWHERE cia.CategoryId IS NULLINSERT INTO Categories(CategoryId, CategoryText)SELECT cia.CategoryId, NULLFROM CategoriesInArticles cia INNER JOIN CSVTable(@ArticleCategories) acON cia.CategoryId = ac.StringLEFT JOIN Categories cON cia.CategoryId = c.CategoryIdWHERE c.CategoryId IS NULLDELETE cFROM CSVTable(@ArticleCategories) ac INNER JOIN Categories cON ac.String = c.CategoryIdLEFT JOIN CategoriesInArticles ciaON ac.String = cia.CategoryIdWHERE cia.CategoryId IS NULLThe first code block seems to work.The second and third does not. The problem is that the CSVTable has only the category text and not categories so I get an error in: ON ac.String = c.CategoryIdI'm not sure if my code is the best way to create the synchronization.Thanks,Miguel |
|
|
jen
Master Smack Fu Yak Hacker
4110 Posts |
Posted - 2007-09-10 : 16:02:12
|
| I was actually coding when I realized you have that csvtable source..fastest is to add the missing column in this csvtable perhaps?--------------------keeping it simple... |
 |
|
|
shapper
Constraint Violating Yak Guru
450 Posts |
Posted - 2007-09-11 : 12:20:44
|
| Hi,Yes, that was what I was trying to do but not able ...The function CSVTable returns a table with only one column: StringWhat I need is to create a new table from this one with 2 columns:StringId and String.StringId will be taken from table Categories given the value of String.Then I will use this new table in all my code blocks.Thanks,Miguel |
 |
|
|
jen
Master Smack Fu Yak Hacker
4110 Posts |
Posted - 2007-09-11 : 12:38:13
|
| why can't you add another column in csvtable?--------------------keeping it simple... |
 |
|
|
shapper
Constraint Violating Yak Guru
450 Posts |
Posted - 2007-09-11 : 21:12:14
|
| Hi,I tried a new code. It creates the article but the categories are not created.Could someone, please, help me out?Here is my new code:INSERT INTO CategoriesInArticles(CategoryId, ArticleId)SELECT c.CategoryId, @ArticleIdFROM Articles c INNER JOIN CSVTable(@ArticleCategories) acON c.CategoryText = ac.StringLEFT JOIN CategoriesInArticles ciaON c.CategoryId = cia.CategoryIdWHERE cia.CategoryId IS NULLINSERT INTO Categories(CategoryId, CategoryText) SELECT cia.CategoryId, NULL FROM CategoriesInArticles ciaJOIN [Categories] c ON c.CategoryId = cia.CategoryIdINNER JOIN CSVTable(@ArticleCategories) ac ON ac.String = c.CategoryTextWHERE c.CategoryId IS NULL DELETE c FROM Categories c INNER JOIN CSVTable(@ArticleCategories) ac ON ac.String = c.CategoryText LEFT JOIN CategoriesInArticles cia ON c.CategoryId = cia.CategoryIdWHERE cia.CategoryId IS NULL Thank You,Miguel |
 |
|
|
dinakar
Master Smack Fu Yak Hacker
2507 Posts |
Posted - 2007-09-12 : 11:56:38
|
| Please post some sample code from each of the tables and expected output.Dinakar Nethi************************Life is short. Enjoy it.************************http://weblogs.sqlteam.com/dinakar/ |
 |
|
|
shapper
Constraint Violating Yak Guru
450 Posts |
Posted - 2007-09-13 : 10:06:27
|
| Hi,I will try to better explain what I am trying to do.I have 3 tables: CREATE TABLE Articles (ArticleId INT, ArticleText NVARCHAR(512)) CREATE TABLE Categories (CategoryId INT, CategoryText NVARCHAR(512)) CREATE TABLE CategoriesInCategories (ArticleId INT, CategoryId INT) Consider the following tables content: Articles Table ArticleId ArticleText 1 Game ended 1-1 2 Book Review Categories Table CategoryId CategoryText 1 Sports 2 Entertainment CategoriesInArticles Table ArticleId CategoryId 1 1 2 2 I need to create the following procedures: CreateArticle Create Procedure [CreateArticle] @ArticleText NVARCHAR(512), @ArticleCategories NVARCHAR(MAX) As Begin ... EndThis procedure should the the following:1. Create the article in table Articles2 .Use the function CSVTable that returns a table with all the categories contained in @ArticleCategories. For each category check if there is already one with the same CategoryText in table Categories. If there is just get the CategoryId and add a new record into CategoriesInArticles with ArticleId and found CategoryId. If there isn't any then create the new Category into table Categories and then add the new record to CategoriesInArticles. DeleteArticle Create Procedure [DeleteArticle] @ArticleId INT As Begin ... End This procedure should the the following: 1. Delete the article in tables Articles and CategoriesInArticles given its ArticleId 2 .Delete categories from table Categories that are no longer associated with any other article (in table CategoriesInArticles) UpdateArticle Create Procedure [UpdateArticle] @ArticleId INT, @ArticleText NVARCHAR(512), @ArticleCategories NVARCHAR(MAX) As Begin ... End This procedure should the the following: 1. Update the values into Articles Table 2 .Use the function CSVTable that returns a table with all the categories contained in @ArticleCategories. I think the easiest way is to delete all the categories from ArticleId as it is done in DeleteArticle. Then It creates the new categories as it is done in CreateArticle.So basically my procedure SynchronizeCategories was suppose to take care of the categories part.It is not working and maybe I should integrate the code in the procedures Create, DeleteArticle and UpdateArticle.Consider I create a new article:EXEC CreateArticle @ArticleText = "Book launched at sports event" @ArticleCategories = "Entertainment, Business"The tables would become: Articles Table ArticleId ArticleText 1 Game ended 1-1 2 Book Review 3 Book launched at sports event Categories Table CategoryId CategoryText 1 Sports 2 Entertainment 3 Business CategoriesInArticles Table ArticleId CategoryId 1 1 2 2 3 2 3 3NOTE: Because there is no category named Business in Categories this must be created. Then I would updated it:EXEC UpdateArticle @ArticleId = "3" @ArticleText = "Book launched at sports event" @ArticleCategories = "Sports, Tech"The tables would become:Articles Table ArticleId ArticleText 1 Game ended 1-1 2 Book Review 3 Book launched at sports event Categories Table CategoryId CategoryText 1 Sports 2 Entertainment 4 TechCategoriesInArticles Table ArticleId CategoryId 1 1 2 2 3 1 3 4 Note: Since Business category is no longer used by any other article then it is also deleted from Categories.The new Tech category is then created and associated with the updated article as well as the existing category Sports.Finally I would delete it:EXEC DeleteArticle @ArticleId = "3"The tables would become:Articles Table ArticleId ArticleText 1 Game ended 1-1 2 Book ReviewCategories Table CategoryId CategoryText 1 Sports 2 Entertainment CategoriesInArticles Table ArticleId CategoryId 1 1 2 2 Note: Since Tech category is no longer used by any other article then it is also deleted from Categories.The Sports category is not deleted from Categories since it is used by Article with Id=1Well, I hope I didn't miss anything and I explained it well.I have been trying my code, either by creating a separate procedure named SynchronizeCategories or inside the Create, Delete and Update procedure.Until now I was not able to make this work. Could someone, please, help me out with this?Thank You Very Much,Miguel |
 |
|
|
jen
Master Smack Fu Yak Hacker
4110 Posts |
Posted - 2007-09-13 : 12:10:49
|
1. to make it easier, you need to change the IDs into identity columns2. I've posted a code for the insert, you should deal with the delete on another procedure, don't put them together3. call the delete first since it's more of a cleanup then the insert procedure--I am not the author of this function, just modified it a bit to trim down the spaces before and after the delimiterCREATE FUNCTION [dbo].[fnSplitText]( @RowData varchar(4000), @SplitOn varchar(5)) RETURNS @RtnValue table ( Row int identity(1,1), Data varchar(100)) AS BEGIN Declare @Cnt int Set @Cnt = 1 While (Charindex(@SplitOn,@RowData)>0) Begin Insert Into @RtnValue (data) Select Data = ltrim(rtrim(Substring(@RowData,1,Charindex(@SplitOn,@RowData)-1))) Set @RowData = ltrim(rtrim(Substring(@RowData,Charindex(@SplitOn,@RowData)+1,len(@RowData)))) Set @Cnt = @Cnt + 1 End Insert Into @RtnValue (data) Select Data = ltrim(rtrim(@RowData)) ReturnENDGOCREATE TABLE #Articles (ArticleId int identity(1,1), ArticleText NVARCHAR(512))CREATE TABLE #Categories (CategoryId int identity(1,1), CategoryText NVARCHAR(512))CREATE TABLE #CategoriesInArticles (ArticleId INT, CategoryId INT) goinsert into #articles(ArticleText )select 'Game ended 1-1'unionselect 'Book Review'insert into #Categories(CategoryText)select 'Sports'unionselect 'Entertainment'insert into #CategoriesInArticles(articleid,categoryid)select 1,1unionselect 2,2godeclare @articletext nvarchar(600),@articlecategories nvarchar(600)set @articleText = 'Book launched at sports event'set @ArticleCategories = 'Entertainment,Business'declare @articleid table(articleid int)declare @categoryid table(categoryid int)if not exists(select * from #articles where articletext=@articletext)begin insert into #articles(articletext) output inserted.articleid into @articleid(articleid) select @articletext insert into #categories(categorytext) select data from dbo.fnsplitText(@articlecategories,',') fst where not exists(select categorytext from #categories where categorytext=fst.data) insert into @categoryid(categoryid) select categoryid from #categories c join dbo.fnsplittext(@articlecategories,',') fst on c.categorytext=fst.data insert into #categoriesInArticles(articleid,categoryid) select a.articleid,c.categoryid from @articleID a cross join @categoryid cendselect * from #articlesselect * from #categoriesselect * from #categoriesinArticles --------------------keeping it simple... |
 |
|
|
shapper
Constraint Violating Yak Guru
450 Posts |
Posted - 2007-09-13 : 16:14:26
|
| Hi Jen,I am trying your code. I have one question. What do you mean with:"3. call the delete first since it's more of a cleanup then the insert procedure"Do you mean I should call the delete procedure before I run the insert or update code ... got lost on that.Thank You,Miguel |
 |
|
|
jen
Master Smack Fu Yak Hacker
4110 Posts |
Posted - 2007-09-13 : 16:20:43
|
| yesi'm simple minded... what i say is as is--------------------keeping it simple... |
 |
|
|
shapper
Constraint Violating Yak Guru
450 Posts |
Posted - 2007-09-14 : 13:54:12
|
| Hi Jen,Thanks for your code.I created the Delete and Update procedures and until now it seems to work fine. I am just integrating some code to integrate error detection ... I found this article and I am using it:http://www.4guysfromrolla.com/webtech/041906-1.shtmlThanks,Miguel |
 |
|
|
|
|
|
|
|