Active Directory modifications using SQL Server - sql

I've exported my AD into CSV and pumped it into SQL, the goal is to modify some fields and import it back into AD.
I've done every field I need to do except one, the proxyAddress field.
My data looks like this:
proxyAddresses
sip:john.smiths#email.com;SMTP:john.smith#email.com
sip:james.jones#email.com;SMTP:james.jones#email.com;notes:james.jones/EMAIL/
etc...
I'm trying to change the sip: values, but as they're all different username, and have SMTP included, I'm struggling with the SQL LIKE command.
I need to data to look like this:
proxyAddresses
sip:john.smiths#newemail.com;SMTP:john.smith#email.com
sip:james.jones#newemail.com;SMTP:james.jones#email.com;notes:james.jones/EMAIL/
Changing the sip: value, but leaving the rest as they are.
Any help would be appreciated.

We don't know the tables definition nor the mapping between new and old values, so just for the start something like this:
declare #e varchar(1000) = 'sip:james.jones#email.com;SMTP:james.jones#email.com;notes:james.jones/EMAIL/'
declare #newEmail varchar(126) = 'james.jones#newemail.com'
select stuff(#e, charindex(':', #e)+1, charindex(';', #e)-charindex(':', #e)-1, #newEmail)

Related

Querying full and sub-strings via multi-valued parameter using SQL

I am building a report with Microsoft SSRS (2012) having a multi-value parameter #parCode for the user to filter for certain codes. This works perfectly fine. Generally, my query looks like this:
SELECT ...
FROM ...
WHERE
TblCode.Code IN (#Code)
ORDER BY...
The codes are of following type (just an excerpt):
C73.0
C73.1
...
C79.0
C79.1
C79.2
Now, in additon to filtering for multiple of these codes I would like to als be able to filter for sub-strings of the codes. Meaning, when the user enters (Example 1)
C79
for #parCodes The output should be
C79.0
C79.1
C79.2
So eventually the user should be able to enter (Example 2)
C73.0
C79
for #parCodes and the output would be
C73.0
C79.0
C79.1
C79.2
I managed to implement both functionalities seperately, so either filtering for multiple "complete" codes or filterting for sub-string of code, but not both simultaneously.
I tried to do something like
...
WHERE
TblCode.Code IN (#parCode +'%')
ORDER BY...
but this screws up the Example 2. On the other hand, if I try to work with LIKE or = instead of IN statement, then I won't be able to make the parameter multi-valued.
Does anyone have an idea how to realize such functionality or whether IN statement pared with multi-valued parameters simply doesn't allow for it?
Thank you very much!
Assuming you are using SQL server
WHERE (
TblCode.Code IN (#parCode)
OR
CASE
WHEN CHARINDEX('.', Code)>0 THEN LEFT(TblCode.Code, CHARINDEX('.', TblCode.Code)-1)
ELSE TblCode.Code
END IN (#parCode)
)
The first clause makes exact match so for your example matches C73.0
The second clause matches characters before the dot character so it would get values C79.0, C79.1, C79.2 etc
Warning: Filtering using expressions would invalidate the use of an index on TblCode.Code

How can I write a WHERE statement that looks for a variable OR Null?

I am attempting to write a query for an Altiris report. This query is looking for machine information. The query works fine, however the problem I am running into is with my parameters. I have set up multiple parameters within Altiris to allow me to filter and search through the report for multiple fields. Then, in my query, I add those parameters into the WHERE statements.
All of the parameters were working fine, until I added Make and Model parameters. We have quite a few machines that do not have information populated into these fields. So when I add in the WHERE xxxx LIKE N'%Make%', I lose about 500 machines based on it now only looking for machines with something in that field. I tried to fix this by adding lines like the following:
Where ((xxxx LIKE N'%Make%' OR xxxx is null))
This kind of worked, in that now the report shows all machines... But if I enter "HP" into the Make parameter field and then rerun the report... it shows all HP machines like I want, but also all of the null machines as well.
How can I rewrite my where statements so that they do not exclude machines in the report, and allow me to filter by all HP machines, without showing null values as well?
Hope this made sense, and thank you
In this snip of code, the last two lines make me lose about 500 machines in my total machine count of the report. It is omitting all machines that have null values.
WHERE
(dbo.OS_Version.[OS Name] LIKE N'%OSName%') AND
(dbo.OS_Version.[OS Version] LIKE N'%Build%') AND
(dbo.OS_Version.Name LIKE N'%Name%') AND
(dbo.Inv_AeX_AC_Identification.[Hardware Serial Number] LIKE N'%Serial%') AND
(dbo.vHWComputerSystem.Manufacturer LIKE N'%Make%') AND
(dbo.vHWComputerSystem.Model LIKE N'%Model%')
This is how I tried to fix it, and now I get all 20,000 machines. But my make/model fields report on null fields as well.
WHERE
(dbo.OS_Version.[OS Name] LIKE N'%OSName%') AND
(dbo.OS_Version.[OS Version] LIKE N'%Build%') AND
(dbo.OS_Version.Name LIKE N'%Name%') AND
(dbo.Inv_AeX_AC_Identification.[Hardware Serial Number] LIKE N'%Serial%') AND
((dbo.vHWComputerSystem.Manufacturer LIKE N'%Make%') OR (dbo.vHWComputerSystem.Manufacturer is null)) AND
((dbo.vHWComputerSystem.Model LIKE N'%Model%') OR (dbo.vHWComputerSystem.Model is null))
I'm guess that if you don't enter a value for a parameter, it's coming through as an empty string, and of course, every varchar is LIKE '%%'.
I'm not sure what RDBMS this is, but if the ISNULL function is available, try this:
where ((ISNULL(xxxx,'') LIKE N'%Make%')
This replaces nulls with the empty string before doing the LIKE comparison.
I think you want something like this:
(cs.Manufacturer LIKE N'%#Make%' OR #Make = '') AND
(cs.Model LIKE N'%#Model%' OR #Model = '')
I am using = '' rather than IS NULL because you are clearly not passing in the parameters as NULL values (the LIKE wouldn't work).
This does not provide a method for filtering to get only the NULL values, because you are using the "special value" for the parameter to mean "don't apply a filter here".
Note that cs is intended as a table alias. I also strongly recommend that you use table aliases so your queries are easier to write and to read.
I think you're looking for something like WHERE ISNULL(Model, '') LIKE '%Model%'. However, you should replace '%Model%' with a variable. The above example would literally match the word 'Model'
DECLARE #Model NVARCHAR(100) = 'T-800'
...
WHERE ISNULL(Model, '') LIKE '%' + #Model + '%'
^ This would not include rows with NULL Model values

SQL Server : remove duplicated text within a string

I have a SQL Server 2008 table with a column containing lengthy HTML text. Near the top there is a link provided for an associated MP3 file which is unique to each record. The links are are all formatted as follows:
<div class="MediaSaveAs">Download Audio </div>
Unfortunately many records contain two or three sequential and identical instances of this link where there should be only one. Is there a relatively simple script I can run to find and eliminate the redundant links?
I'm not entirely sure - because your explanation wasn't very clear - but this appears to do what you want, although whether or not you consider this to be a "simple script", I don't know.
declare #Link nvarchar(200) = N'<div class="MediaSaveAs">Download Audio </div>'
declare #BadData nvarchar(max) = N'cbjahcgfhjasgfzhjaucv' + replicate(#Link, 3) + N'cabhjcsghagj',
#StartPattern nvarchar(34) = N'<div class="MediaSaveAs"><a href="',
#EndPattern nvarchar(27) = N'">Download Audio </a></div>'
select #BadData
select replace (
#BadData,
substring(#BadData, charindex(#StartPattern, #BadData), len(#BadData)-charindex(reverse(#EndPattern), reverse(#BadData))-charindex(#StartPattern, #BadData) + 2),
substring(#BadData, charindex(#StartPattern, #BadData), charindex(#EndPattern, #BadData) + len(#EndPattern) - charindex(#StartPattern, #BadData))
)
Personally I would not like to have to maintain this code; I would far rather use a script in another language that can actually parse HTML. You said this is "just a repeated text issue", but that doesn't mean it's an easy problem and especially not in a language like TSQL that has such limited support for string operations.
For future reference, please put all relevant information into the question - you can edit it if you need to - instead of leaving them in the comments where they are difficult to read and may be overlooked. And please post sample data and results instead of describing things in words.
First we need to identify the file names, which we can do with PATINDEX:
select
substring(html, PATINDEX('%filename%.mp3%', html), PATINDEX('%.mp3%', html)-PATINDEX('%filename%.mp3%', html)+4)
from files
And then secondly identify and the duplicates, check it out:
delete
from files
where id not in (
select max(id)
from files
group by substring(html, PATINDEX('%filename%.mp3%', html), PATINDEX('%.mp3%', html)-PATINDEX('%filename%.mp3%', html)+4)
)
http://www.sqlfiddle.com/#!3/887a3/5

MOSS 2007: What is the source of "Directories"?

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?
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.
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:
[Webs].[FullUrl] for the web, containing list, containing item.
[AllDocs].[tp_Leaf] for the list, containing item.
Concatenate the following 2 components to get tp_Leaf for an item:
(Item count in the list) + 1
'_.000'
Regards,
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.
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).

set up way of getting mysite.$domain

I have several domains, only one website and one databse table for each domain.
example: wbesite.us - data from USA goes to database table main_usa
wbesite.co.uk - data form UK goes to database table main_uk
Only have one database with name of the website. Having only one website structured and having variables like this:
$sql="select * from main_".$countrycode." where bla..bla...
and many other variables to catch the domain extension, and so on...
Now, instead of having one full website for each domain, how can set a script and wher do I put it in order to detect the domain that the user uses.
In my server root do I create something like website.$domain?
Something like website OLX but for different purposes.
I hope I made myself clear.
Thank you.
You could use the $_SERVER['SERVER_NAME'] global and somehow parse it, to get the country code.
I didn't try it, but something like this should work:
$servername_array = explode('.', $_SERVER['SERVER_NAME']);
$country_code = array_pop($servername_array);
That way, $country_code will be com, uk, or whatever is after the last dot in the domain name.