Who needs people?

Whoever isolates himself seeks his own desire;
he breaks out against all sound judgment. Proverbs 18:1

Last week I wrote a bit about parenthood. I’ve been dwelling a lot on fatherhood and that’s forced me to take a good look at some of my weaknesses. One trend I’ve noticed is that I tend to isolate myself. I think I can get along fine without other people, but the truth is that I need people.

I think I first started to notice this at a past job. It was a tough job and I worked long hours but I couldn’t seem to get enough of it. But one by one valued co-workers left and as they left the job slowly became unbearable. The work was pretty much the same but it the team was falling apart. It was the team that drove me on to accomplish great things.

I eventually changed jobs and my enthusiasm was renewed but after a couple of years at that job once again my energy started to drain. It was really charged up back in November when I attended 2010 PASS Summit. Being around people who were excited about technology infused me with a new passion for what I was doing.

But it goes deeper than the job. I love my job but my job is not my life. I recently started attending a weekly meeting of men who are trying to be open about our problems and struggles. It was in listening to the stories they told – burdens they no longer feel able to carry, dreams that have been shattered, addictions they’ve been keeping secret – that I was able to first articulate the pains I’ve had that have driven me to do some pretty awful things: lies, betrayals, etc.

At heart I believe people are primarily creatures who need relationships. There is something in us – planted by God – that needs to connect.

My tendency is to retreat but I see now that I need to start investing in relationships. I know this will help my career but I’m hoping it will help me in all areas of life.

I’d like to leave you with a challenge. Can you list in the various areas of your life – work, personal, spiritual, etc – the people you can count on?

Posted in Business, Life, Parenthood, spirit | Tagged , , | Leave a comment

Downloading the results of a Twitter Search using PowerShell

I’m trying to learn PowerShell because I need to automate some things. I was a little skeptical about all the hype surrounding PowerShell. What could it possibly do the Perl didn’t? But I knew it integrated really well with .NET and after reading Andy Warren’s post I figured PowerShell made sense. Even Paul Graham thinks for automation or glue programs you want to use the language that has the libraries you need and not LISP. When Paul Graham says “don’t use LISP” you have to listen, right?

It turns out PowerShell is pretty fantastic.

@Kendra_Little asked: “Is there a way to search the archives of #sqlhelp? Trying to remember answer to a question i know i saw a couple months ago.”

@anonythemouse suggested she use PowerShell to search Twitter and archive the results.

I was just beginning to get interested in PowerShell so I decided to see if I could do this. I figured learning how to do this would help me learn PowerShell even if this particular script didn’t have much of a shelf life. But it might end up being very useful in itself. There might be other searches that I’d want to archive or I might decide that I don’t like some aspect of the GUI to whatever tool I’m using to interact with Twitter or I might want to pipe Twitter data into some application I’m writing.

Well, how easy is it to get Twitter search data using PowerShell? Actually, it’s incredibly easy.

I lifted this code from Windows PowerShell in Action
by Bruce Payette.

([xml](new-object net.webclient).DownloadString(
"http://blogs.msdn.com/powershell/rss.aspx"
)).rss.channel.item | format-table title,link

I had to modify it slightly to switch from RSS to Atom and I removed the formatting because I want to play around with things a bit.

([xml](new-object net.webclient).DownloadString(
"http://search.twitter.com/search.atom?q=%23sqlhelp&show_user=1&rpp=100"
)).feed.entry

So that is how to get a search of Twitter into PowerShell almost no code. (Note, you can get the URL for the Atom feed of a Twitter search by searching here and then looking for “Feed for this query” link on the results page. Other options you might want to put in your URL are described here)

Anyway, we’re not quite where I want to be. I’d like to get rid of some of the meta-data I don’t want. So we’ll step through the collection. We can use the ForEach-Object to do this. I’m going to use an alias of the ForEach-Object – %. It’s just a quick way of writing ForEach-Object. And I’ll be using a special variable $_. $_ basically refers to the current object.

([xml](new-object net.webclient).DownloadString(
"http://search.twitter.com/search.atom?q=%23sqlhelp&show_user=1&rpp=100"
)).feed.entry |
%{
	$_.title
	$_.published
	"

	"
}

I’m adding a | which means direct the output of this command into the next command. The next command is the ForEach-Object alias and then we apply the code between the {} to each object in the Atom feed we got from Twitter. I then output the title attribute which is essentially the tweet and the published attribute which tells me when the tweet was made. (The blank lines between the double quotes are just to make the output easier to read.)

Now, to get it into my database I could invoke sqlcmd or export this data to a file. In the long run I think storing it in a database would be a good idea but I don’t want to muddy the waters with that just yet. Instead I’ll export it to a file.

$file = ([xml](new-object net.webclient).DownloadString(
"http://search.twitter.com/search.atom?q=%23sqlhelp&show_user=1&rpp=100"
)).feed.entry |
%{
	
	$title = $_.title -replace ("`t"," ")
	$published = $_.published -replace ("`t"," ")
	$title + "`t" + $published
	
} 

$file  | out-file -filepath sqlhelp_twitter.txt -encoding Ascii

There you have it. A tab-delimited file of a Twitter search. It only gets the last 100 Tweets but the Twitter Search API shows you how to page through the results.

I hope to expand on this example a bit and maybe do some more interesting things with the Twitter API and the Twitter Search API. But the point is that PowerShell lets you do some pretty neat stuff in a fairly small amount of code. Reminds me of my Perl days. In fact, PowerShell seems as exciting to me as when I was first learning Perl.

Posted in PowerShell | Tagged , , , , , | 2 Comments

T-SQL Tuesday # 13 – Asking the business good questions


Fatherhood involves more than just having dried food on your shirt. People expect you to do crazy things like wave your arms like a muppet or impart wisdom to the next generation. I don’t know that I have much wisdom but I have had a few moments of clarity that I hope I can pass on to little Zeke and any brothers or sisters he might someday have.

One of those moments of clarity came during Warren Thornthaite’s PASS Summit session on dimensional modelling. He said – and I’m paraphrasing here – don’t ask users what they want, ask them what they do.

It was in reflecting on this that I really latched on to the power of asking good questions. I had been doing this for a while but had not reflected on what it was I was doing.

Soon after starting my current job one of the BAs realized that I could be counted on to discover database problems quickly. He would often call or email vaguely defined issues like “a user says this number doesn’t seem right”. But usually I could get to the root of things quickly. Sometimes I would discover bugs. Sometimes I would discover that the number was accurate based on the inputs and the business rules. The number was just not what the user expected – or perhaps hoped.

After a certain time I spent more and  more of my time discovering things in the later category and decided that I needed to cut down on the number of false bug reports. I started asking questions of the BA. “How did the user discover the bug? What do they think the number should be and why?” And the BA quickly discovered that as he asked the users these questions many of the bugs disappeared.

There was nothing disrespectful in the way we asked these questions. We knew we could not trust that the user was always right. And we found that asking good questions was a great tool to help us cooperate with the users and help them better understand their data.

Asking good questions also seems to be helpful in all sorts of other situations, too. When I see two co-workers getting frustrated trying to communicate sometimes a good question helps alleviate the problems.

I’d like to say I’ve used this skill a lot in my personal life – with my family, as I try to grow spiritually, etc. But I have to admit this is an area I’m still working on.

I do sort of wonder why there are certain skills that come easily at work but not at home.

Anyway, what are some good questions you ask? What would you like people to ask you?

Posted in Business, Life, Parenthood | Tagged , , , , , | 3 Comments

Generating Random Data for Testing

Recently I was faced with the need to generate lots of data for a presentation. There is a temptation in situations like this to grab some data from a production system and obfuscate it somehow. My advice to you is DON’T DO IT! I know you think your obfuscation algorithm will render the data completely safe but security is a tricky thing. Why expose your data to people if you don’t have to? (There may also be legal requirements or corporate requirements that you not do this.)

Anyway, it turns out generating random data is not that hard. There are some gotchas. Brian Knight points out that simply relying on the RAND() function will get you in trouble because it only provides on number per result set. He does supply a work around to this using the NEWID() function. He also points to another solution using a view and a UDF that he attributes it Itzik Ben-Gan. We’ll be using both of these techniques in this post.

Let’s say for your demo you want a table of project start dates for a contracting company. You want a GUID for the project ID, DATETIMEs for the start time and end time of the project and an INT which is the ID for your hypothetical document management system.

Here is the schema

if object_id(N'tblProjectDates') is not null
	drop table tblProjectDates

create table tblProjectDates (
	project_id uniqueidentifier not null
	,start_dt datetime
	,end_dt datetime
	,document_id int
	
)

We’ll also need a “numbers” table. (For more on these sorts of tables see this article or this article.

Here is a slightly modified version of the code from the simple-talk.com article:

if object_id(N'tblNumbers') is not null
	drop table tblNumbers

    BEGIN
    CREATE TABLE [dbo].tblNumbers(
     [number] [int],
    CONSTRAINT [Index_Numbers] PRIMARY KEY CLUSTERED
    (
     [number] ASC
    ) ON [PRIMARY]
    ) ON [PRIMARY]

    DECLARE @ii INT
    SELECT @ii=1
    WHILE (@ii<=10000)
     BEGIN
     INSERT INTO tblNumbers(NUMBER) SELECT @II
     SELECT @II=@II+1
     END
    END 

So, the first thing we need is the GUIDs. This is the easy part.

This query will give us 10000 GUIDs

select n.number, NEWID() as project_id

from tblNumbers n


Now we need to generate dates in the past for our start date. We’ll need the code from Brian Knight’s article:

if object_id(N'VRand') is not null
	drop view VRand 

go

CREATE VIEW VRand
AS
  SELECT RAND() AS rnd
GO


if object_id(N'dbo.fn_row_rand') is not null
	drop function dbo.fn_row_rand

go

CREATE FUNCTION dbo.fn_row_rand() RETURNS FLOAT
AS
BEGIN
  RETURN (SELECT rnd FROM VRand)
END

go

I’m going to create a variable called @date_seed and use that to make the dates look nicer instead of calling GETDATE() in the body of the CTE

So, here is our insert statement:

declare @date_seed datetime
select @date_seed = convert(datetime,convert(nvarchar,getdate(),101))

;with start_dt as(
	select top 10000 dateadd(d,0-floor(dbo.fn_row_rand() * 3651),@date_seed) as start_dt
	,ROW_NUMBER() OVER(order by (select null)) as rn
	from tblNumbers n
	order by NEWID()
	
)
insert into tblProjectDates
(project_id, start_dt)
select NEWID() as project_id, s_d.start_dt


from tblNumbers n

inner join start_dt s_d
on n.number = s_d.rn

Let’s inspect the data:

select * from tblProjectDates

We get project IDs and start dates. (All the start dates are for the last 10 years. That’s where the 3651 number above comes into play.)

Now, we need end dates and those have to be in the future. So, we’ll just use DATEADD and the same fn_row_rand function to get those. Except we’ll be DATEADDing to the start_dt instead of GETDATE(). And we won’t use the “0 – ” since we want the end dates to be after the start dates. Also, we’ll convert all future dates to be NULLs and assume that means the project is on going if the end date is unknown. (You could make up some kind of place holder if you don’t want NULLs.) Lastly, we’ll assume that no project lasts more than 150 days so we’ll multiple the random number by 150.

Here’s the update for end_dt

;with end_dt as(
select pd.project_id
, dateadd(d,floor(dbo.fn_row_rand() * 150),pd.start_dt) as end_dt
from tblProjectDates pd
)
update tblProjectDates
set end_dt = case when e_d.end_dt <= getdate() then e_d.end_dt else null end
from tblProjectDates pd
inner join end_dt e_d
on pd.project_id = e_d.project_Id

And here is how our data looks:

select * from tblProjectDates

At this point I’m sure you can see how generating a random INT is trivial. So let’s wrap this up with the final update:

update tblProjectDates
set document_id = dbo.fn_row_rand() * 10000

And here is our data:

select * from tblProjectDates

I’m hoping to talk about generating random strings for names, etc. Obviously you could just cast a NEWID as an NVARCHAR to get a string but they don’t look much like names. I don’t know if there is a quick way to do it but I have some ideas. If anything looks worth sharing I’ll try and get it on here.

Any thoughts on this? Please leave a comment or email me!

Posted in Testing | Tagged , , , , , , , | 6 Comments