tags:

views:

79

answers:

4

Hello all,

I'm trying to generate a new SharePoint list item directly using SQL server. What's stopping me is damn tp_DirName column. I have no ideas how to create this value.

Just for instance, I have selected all tasks from AllUserData, and there are possible values for the column: 'MySite/Lists/Task', 'Lists/Task' and even 'MySite/Lists/List2'.

MySite is the FullUrl value from Webs table. I can obtain it. But what about 'Lists/Task' and '/Lists/List2'? Where they are stored?

If try to avoid SQL context, I can formulate it the following way: what is the object, that has such attribute as '/Lists/List2'? Where can I set it up in GUI?

+1  A: 

Just a FYI. It is VERY not supported to try and write directly to SharePoint's SQL Tables. You should really try and write something that utilizes the SharePoint Object Model. Writing to the SharePoint database directly mean Microsoft will not support the environment.

John Ptacek
If anybody read this, you have to know that's the scariest mistake you can make, when writing an SP app that's complex enough. NEVER (ever, ever) try to implement things through OM, CAML etc. It cost me a half of the year to write OM version then realize that it is slow, cannot be perfomance optimized and I just can't make all features I want. What is the most important thing you have to know about wars? Don't fight at war. What is the most important thing I've learned after 6 months of using crappy MS SP OM? Don't use it at all.
noober
P.S. Except rare situations (for instance, fields validation and some sort of web parts) when you cannot avoid SP OM.
noober
I still would not recommend it, you are making changes to something that is essentially a blackbox and expect things to run smoothly. This is not a responsible approach.
Vladi Gubler
And I still would not recommend using OM if you are able to avoid it. It's not just more optimized, but even simpler. Just compare 1) CAML batch update query with corresponding SQL query 2) copying value from one item's column to another column of another item (types can mismatch).
noober
While what your saying MAY be true, noober, howerver besides that its prohibited by EULA and therefore totally unsupported by Microsoft (probably for a reason), it can actually lead to performance and incorrect data problems: http://www.codeproject.com/KB/sharepoint/5-reasons-not-query-sp-db.aspx?msg=3225155
Janis Veinbergs
AFAIK, there is no more EULA for MOSS. EULA was presented for SharePoint *2003*. Now the document is named PUR. Second, could you please quote the paragraph, where direct access to DB is *prohibited*? Third, what kind of support do you mean? MS will not help you write your solution anyway. If you mean documentation, there *is* official WS_Content description here: http://msdn.microsoft.com/en-us/library/dd358229(PROT.13).aspx And it is NOT worse than OM documentation, which has a lot of lacks and dumb no-sense sentences like "Method SetMyProperty gives you opportunity to set MyProperty value."
noober
http://msdn.microsoft.com/en-us/library/bb861829.aspxhttp://support.microsoft.com/kb/841057/en-us
Ryan
We had a situation with a production problem that we could resolve by running a store procedure in the SharePoint database. We could not resolve the issue via the OM. We needed to get permission from Microsoft to run the stored proc on an Enterprise customer's production database or else our customer would have not been able to get support for production issues in the future.
John Ptacek
Ryan, there is a little difference between "is not recommended" (from the article you have linked) and "is prohibited" (from Janis reply). John, thanks for detailed answer, our customers do not need such kind of support. They want instead features, speed etc. OK, everyone, let's stop flooding the question. If you think OM is good enough for you, have a joy developing what you want through OM.
noober
Well noober we are all big boys here and we have to make tradeoffs every day. If this is the best way to realistically do what you have to do then thats your pragmatic decision to make. Just be aware that you are juggling with hand grenades (i.e. if it goes wrong it will go wrong very badly) and blanket statements like "SP OM Don't use it at all" are not very helpful.
Ryan
Yeah, but there was an important specification: "when writing an SP app that's complex enough". Ask John, why they "could not resolve the issue via the OM". If you ask me, I can talk about examples for hours. You cannot use the same event handler class twice (there is a trick with hundred empty derivatives - nice enough, yeah?), the handlers are asynchronous and stopped by predefined timer (no choice!), CAML doesn't support complex queries and if you need one - welcome, loop with 2 SQL queries per iteration (1K items - 2K queries!) etc. etc. On a large project you will meet one of them 100%.
noober
+1  A: 

I've discovered, that [AllDocs] table, in contrast to its title, contains information about "directories", that can be used to generate tp_DirName. At least, I've found "List2" and "Task" entries in [AllDocs].[tp_Leaf] column.

So the solution looks like this -- concatenate the following 2 components to get tp_DirName:

  1. [Webs].[FullUrl] for the web, containing list, containing item.
  2. [AllDocs].[tp_Leaf] for the list, containing item.

Concatenate the following 2 components to get tp_Leaf for an item:

  1. (Item count in the list) + 1
  2. '_.000'

Regards,

noober
A: 

Well, my previous answer was not very useful, though it had a key to the magic. Now I have a really useful one.

Whatever they said, M$ is very liberal to the MOSS DB hackers. At least they provide the following documents:

http://msdn.microsoft.com/en-us/library/dd304112(PROT.13).aspx http://msdn.microsoft.com/en-us/library/dd358577(v=PROT.13).aspx

Read? Then, you know that all folders are listed in the [AllDocs] table with '1' in the 'Type' column.

Now, let's look at 'tp_RootFolder' column in AllLists. It looks like a folder id, doesn't it? So, just SELECT the single row from the [AllDocs], where Id = tp_RootFolder and Type = 1. Then, concatenate DirName + LeafName, and you will know, what the 'tp_DirName' value for a newly generated item in the list should be. That looks like a solid rock solution.

Now about tp_LeafName for the new items. Before, I wrote that the answer is (Item count in the list) + 1 + '_.000', that corresponds to the following query:

DECLARE @itemscount int;
SELECT @itemscount = COUNT(*) FROM [dbo].[AllUserData] WHERE [tp_ListId] = '...my list id...';
INSERT INTO [AllUserData] (tp_LeafName, ...) VALUES(CAST(@itemscount + 1 AS NVARCHAR(255)) + '_.000', ...)

Thus, I have to say I'm not sure that it works always. For items - yes, but for docs... I'll inquire into the question. Leave a comment if you want to read a report.

noober
A: 

Hehe, there is a stored procedure named proc_AddListItem. I was almost right. MS people do the same, but instead of (count + 1) they use just... tp_ID :)

Anyway, now I know THE SINGLE RIGHT answer: I have to call proc_AddListItem.

UPDATE: Don't forget to present the data from the [AllUserData] table as a new item in [AllDocs] (just insert id and leafname, see how SP does it itself).

noober