Tuesday, July 29, 2008
Orange Crush, final Round
This was our last series against Orange Crush, and I wish I could say we won at least one game, but they ended up creaming us both games. And I also wish I could say we just played poorly; but I can't do that either. We played well considering the circumstances; they just played that much better this week. Which makes it that much harder to swallow.
We decided to change some things up this week. I ended up playing right and right-center both games instead of my usual 1B. An interesting move for me since I haven't played outfield in over a year now, but it seemed to work out alright I suppose after I shook the dust off. The first game a pop fly came almost right to me, but I missed it. It hit my glove but I took one step to many forward and the ball grazed the top of my glove and rolled out. That was the only one I dropped, but still pretty disappointing. We also changed up some of the infield, moving our 2B over to first and one of our right fielders to 2B. It was working alright until they started to find the holes.
One of our weaker players who normally plays in right got moved to 3B in the second game, she has tried to play there before. We try to close up the whole in the outfield, and just have our shortstop cheat over a bit and cover 3rd as well. Now I didn't find this out till the ride home, but The Fiancee (and score keeper) said that the other team tried to get us to remove this player from 3rd since they were scared of hurting her. Now she doesn't have the most athletic stance in the world while playing ball, but she knows that a risk of playing ball is potentially getting hit. We say we aren't going to remove her, that she is on our roster and signed the waiver and she wants to play. So after this dialog with the Ump and our other team captain a batter comes up, who we know can hit, intentionally hits a little dribbler to her as if to prove their point. And I wish I could say she scooped it up and got him out at first, but she didn't. I think he may have even gotten to second on that.
For some reason I felt more detached from this game. Maybe it was because I was not playing the infield so I missed a lot of stuff. Maybe it was because they just rolled over us. Maybe it was because I was fed up with all the high school drama that has been floating around these past few weeks. I dunno but it was weird.
With those two wins Orange Crush are now the league champions. There are a few more games to play, but they have won it. No team can catch them now. My hat is off to them.
Next week we play another hard team, the Tornados. These guys were the only other team to beat Orange Crush. So we'll see how we do this week.
Labels: Softball
posted by Tom Becker at
|

Wednesday, July 23, 2008
Newbies and Orange Crush
So I know I haven't posted about softball for the past two weeks. That is partly because of all the drama that has happened around this little blog. People have gotten upset, and tried to start stuff behind the team's back and it is childish. I can write whatever I want here and I plan to. If people don't like it, well I'm sorry. If you don't like something then put on your big boy/girl pants and talk to me. There is a comments section, you really want to say something (yes they are moderated, but if it is nothing to bad I'll usually post them).
So I'm going to write about both games here.
The one two weeks again was against the Newbies, but it was two weeks ago so I don't remember all that much about the game. I know they beat us both games. But I think they were pretty close both times. I do remember one thing that upset me.
So I think it was the second game and our left-center fielder (we play 4 outfielders) fields a ball. He doesn't catch it in the air, but on a bounce. So instead of throwing the ball in to the infield he decides to run down the guy who just hit the ball who is rounding 2nd. Our outfielder is pretty fast, he is defiently a runner, but there is no reason to do that. Just a dumb move. He tags the guy out a few feet from home plate but that is beside the point.
Other than that I think the games were rather uneventful. We lost but good games over all.
--------------------
Last week's game was against Orange Crush again. We were no longer the only ones to defeat them. The Tornadoes beat them two weeks ago, but they are still the first place team in the league. There was a bit of tension on the field between us because of the aforementioned drama. We will also be playing Orange Crush for this next week's game.
The series was kinda like first time we played them. They kinda ran away from us the first game, but we still played very well, even though we were down a player and had to take a ghost out. We even got our first double play of the season I think. Our shortstop caught a ball in the air, that the runner on first didn't think she could get. So the runner is over halfway to second. Short throws to me, and we beat the runner to the bag. It was pretty cool. Like I said I think it was the first one of the season for us. I think if we moved where our ghost out game up in the line up we could have possibly done better. We left a lot of people on base because of it.
The second game was a bit more interesting. Reminicient of the first series this was a very close game. The last inning we were even tied it up, but more on that in a minute. We are playing very well again this game with batting being very good, even some of our weaker hitters were making good contact, may not have gotten on base but were making good contact none the less. Toward the middle of the game we noticed a bit of in fighting again on their bench. For such a well put together team on the field I am surprised to hear some yelling coming from the dugout. So fastforward to the last inning. They have home team advantage so they get to bat last. We tie the game, and have a runner on first, and a one of our bigger guys comes up to bat. He can really drive it out there if he wants to, and we have the ghost out up after him. So since they already have 2 outs, they tell the ump that they are going to walk this batter just to get the ghost out, and with that they close out this half of the inning.
Was it a legal? Yes. Was it very sportsman like? No. I realize that it was strategy, and that in their minds it was a very smart move, but come on. If you compare our
records, they really have nothing to worry about.
So we take the field, and their very first batter hits a home run and finishes the game, and that was all she wrote for that ball game.
So this Sunday is against Orange Crush again, and we'll see how we do. We are getting very close to the end of the summer season. After that a little break and then on to Fall Ball.
Labels: Softball
posted by Tom Becker at
|

Thursday, July 17, 2008
Looping Through a Comma Delimited String in Oracle
Normally when I have to loop through an list of items to insert into a database I use VB to loop through the array and then insert each item individually. However, this poses some problems if everything has to be done as one unit of work (for more background see previous post). So instead of doing the looping in VB, i had to do the loop in P/L SQL.
I found an
article that told me how to do this quite easily. I typed in all the code and syntactically it was correct. I was happy since I thought I was going to have to do some weird string manipulation to go through each of items I was passing in. However what that article doesn't tell you, is that the comma_to_table function does not work for integers. It will throw the following error:
ERROR at line 1:
ORA-00931: missing identifier
ORA-06512: at "SYS.DBMS_UTILITY", line ###
So after about 20 more minutes of research I came across another person having the same problem, and he wrote
his own function that would act the same as the comma_to_table function but it would accept numbers in the delimited string.
His function is called delimstring_to_table (code example below) and it works beautifully. He also includes in his util package a table_to_delimstring function that will do the reverse. I haven't used it but I assume that it works just as well.
I am not going to include the package information on my site, you are going to have to visit the above link for that. I am just going to show the use of his functions:
--declare variables
temp_tab util.varchar2_table;
table_len number;
--convert comma delimated array to table.
util.delimstring_to_table('1,4,90,5,2', temp_tab, table_len, ',');
--loop through array and do inserts
for i in 1..table_len
loop
INSERT INTO someTable
(ID, description)
VALUES
(IN_ID, temp_tab(i));
end loop;
So as you can see looping is pretty easy in P/L SQL. You can use the comma_to_table in place of the delimstring_to_table function if your delimited string is just alpha characters and the loop will work exactly the same way.
Labels: Oracle
posted by Tom Becker at
|

Wednesday, July 16, 2008
Transactions in VB.Net and Oracle
This is going to be kinda a two part post. Each talking about an approach to the same problem. But first some background.
I am creating a questionnaire that is being saved to the database in a mutli-step process. 4 steps to be exact. If any one of those steps fail I want to be able to roll back to the beginning so I don't have a stub of a questionnaire floating around. I need that process to be
atomic.
I originally wrote it so that the 4 steps were independent of each other so that it could be as flexible as possible. And then the problem of the stubs came up. So I had to make it atomic. So since I already had four functions and 4 stored procedures in Oracle I created a transaction in .Net and just added it to my command objects (Part 1 of this article), but that didn't work for me. So then I went to combining all 4 procedures into one and using Oracle transactions (Part 2).
Part 1: .Net Transactions
.Net transactions aren't actually that hard, In my case I was using the
OracleTransaction class but there is a SQLTransaction class that works the same way for those of you using MS-SQL. Essentially you tie your transaction to your connection and your command object. You must use the same connection for each command object, but that is pretty much your only limitation. The most common implementation that I've seen is just passing the connection and the transaction to all the functions that needed it and that is what I did as well. Code examples below:
Private Sub Save()
Dim conn As New OracleConnection("ConnString")
Dim trans As OracleTransaction
conn.Open()
Try
trans = conn.BeginTransaction
saveThingOne(conn, trans)
saveThingTwo(conn, trans)
trans.Commit()
Catch ex As Exception
trans.Rollback()
End Try
End Sub
Private Sub saveThingOne(ByVal conn As OracleConnection, ByVal trans As OracleTransaction)
Using comm As New OracleCommand("Save_Thing_One_Stored_Procedure", conn, trans)
comm.CommandType = CommandType.StoredProcedure
comm.Parameters.Add("IN_ID", OracleType.Number).Value = intID
comm.Parameters.Add("IN_THING_ONE", OracleType.VarChar, 60).Value = strThingONe
comm.ExecuteNonQuery()
End Using
End Sub
Private Sub saveThingTwo(ByVal conn As OracleConnection, ByVal trans As OracleTransaction)
Using comm As New OracleCommand("Save_Thing_Two_Stored_Procedure", conn, trans)
comm.CommandType = CommandType.StoredProcedure
comm.Parameters.Add("IN_ID", OracleType.Number).Value = intID
comm.Parameters.Add("IN_THING_TWO", OracleType.VarChar, 60).Value = strThingTwo
comm.ExecuteNonQuery()
End Using
End Sub
However, in my current environment we use stored procedures for all of our database interactions. And that being the case it makes using the .Net transactions impossible to use. Now I don't know if the above code would work in a MS-SQL environment, but in an Oracle environment it does not. The best reason I can figure it is because Oracle treats a stored procedure as a transaction in and of it self. So when you get to the end of the stored procedure it does a full commit automatically...hence nothing to rollback. So I had to combine all 4 procedures into one massive one and use Oracle transaction statements to make sure everything is done at once.
Part 2: Oracle Transactions
There are a lot of articles out there about Oracle transactions, but I found that most of them had all the information that I needed separated out across multiple pages. So here it is all together.
As I mentioned above an Oracle stored procedure does a commit on successful completion of the procedure. But you can also explicitly tell it to do the commit any time you want to during its execution by calling the "commit;" command. You can also rollback at any point if you want to just by calling the "rollback;" command. If you put the two together you have the beginning of a nice way to ensure an atomic transaction.
The only other new part of the stored procedure you must add is a an exception clause. This as you may guess works much like a try/catch clause in VB. You can either catch specific Oracle errors by calling them by name, or you can do a catch all and just handle all of them the same way, which is what I did below. The only thing I would warn you about though, is that if you are having trouble with your procedure and are still testing I wouldn't put the exception clause in there quite yet. Oracle will catch and handle the error and end cleanly. You will not know that your code is bombing. It took me a while to figure out why it was performing a rollback and exiting clean.
So here is the code for a transaction in Oracle:
PROCEDURE SAVE_TWO_THINGS(
IN_THING_ONE IN VARCHAR2,
IN_THING_TWO IN VARCHAR2
)
IS
BEGIN
INSERT INTO TABLEONE
(ACTIVE, THING_DESC)
VALUES
('Y', IN_THING_ONE);
INSERT INTO TABLETWO
(ACTIVE, THING_DESC)
VALUES
('N', IN_THING_TWO);
COMMIT;
EXCEPTION WHEN OTHERS THEN ROLLBACK;
END;
Note that the 'OTHERS' keyword in my exception clause is where you would catch a specific oracle error, you can string together as many of those as you want to, but I would recommend using the 'OTHERS' as a kind of catch all at the end if you want to make sure you catch everything.
Summary: Unless you are using inline SQL to connect to your Oracle database then you're really not going to be able to use .Net transactions. So you are going to have to use the Oracle transaction. Many would argue that I should have done that from the beginning since Oracle is such a powerhouse that doing processing there isn't a big deal so any atomic transaction should be tried to be done in Oracle anyway, but I really think it is up to the programmer. It really is personal preferences.
Labels: .NET, Oracle, SQL
posted by Tom Becker at
|

Wednesday, July 9, 2008
Using statement versus Try/Catch
So I had a code review this morning and learned of a better way to handle some of my error handling and garbage collecting.
I was using a try/catch/finally block to handle catching errors when calling a database function and then doing all my disposes and clean up in the finally. Now if I was doing something with the error rather than just re-throwing it up to the next layer that would have been fine. But since I wasn't really handling the error at this point there was no reason for me to have all the over head of a try catch block. And as for my disposes there were more elegant solutions to make sure I dispose of all my objects. Enter the Using statement.
This was the first I heard of it. I have spent the afternoon changing most of my data layer code over to it. It allows you to explicitly define a variable that will automatically dispose of itself once it gets to the end of the using block. So it has a very narrow scope. And as for the errors, since those were bubbling up and being caught at the next level there was no need for me to catch them here.
So my code went from this using try/catch/finally:
Dim oConn As New OracleConnection
Dim oComm As OracleCommand
oConn.ConnectionString = "connString"
Try
oConn.Open()
oComm = New OracleCommand("procedurename", oConn)
oComm.CommandType = CommandType.StoredProcedure
oComm.Parameters.AddWithValue("PARAM", param)
oComm.ExecuteNonQuery()
Catch ex As Exception
Throw ex
Finally
oConn.Close()
oConn = Nothing
oComm = Nothing
End Try
To this using the 'Using statement':
using oConn as new OracleConnection("connString")
using oComm as New OracleCommand("procedurename", oConn)
oConn.Open()
oComm.CommandType = CommandType.StoredProcedure
oComm.Parameters.AddWithValue("PARAM", param)
oComm.ExecuteNonQuery()
end using
end using
I think it makes it look a lot cleaner and it removed about 10-15 lines of code per function.
Labels: .NET
posted by Tom Becker at
|

Monday, July 7, 2008
An Open Letter to the Annoying Guy on the Plane
Hi,
You prolly didn't notice me that much since you were absorbed in your conversation and what not but I was the guy sitting one row back and one row over from you on the plane from Minneapolis to Richmond this weekend. I just wanted to let you know that the other people around you, excluding maybe the person who you were talking to, do not care how great you think you are.
I know you worked on the Obama campaign here in Richmond and that you are supposedly at the top of your Ecology class (a point you made several times), but truthfully I really don't care. I am also a little confused on why you feel the need to announce the fact to the whole back half of the plane.
I first saw you in the actual airport when you pulled out your uber-trendy laptop for all to see. And I could tell, just by looking at you, that we prolly wouldn't get along. So imagine my surprise when you proved me right, by constantly telling the person sitting in front of me how great you were. And the comment that really sealed the deal for me not liking you was "2nd graders do not have any 'political self-awareness'." What the heck kinda jacka$$ed comment is that. They are in second grade, setting aside the the whole 'self-awareness' part of the comment. Second graders are just learning how to tell time (according to the VA Standards of Learning) do you really expect them to understand the complexities that is the American government?
So I just wanted to let you know that while you think you're great and all your pseudo-intellectual comments may impress some, I was not impressed.
I am glad that you made a personal connection with someone on the plane, and that the two and a half hours flew by for you while talking to her. My having to listen to you over my headphones made that flight feel longer than the time my sister dragged me to see the movie
Titanic.
Thanks for understanding,
~tom
Labels: rant
posted by Tom Becker at
|

Cheat Sheets
I was just going through some old files and found a couple of cheat sheets that I made for the interns at my last job. And I just thought that I'd share them with you all.
The first one is just some basic
.Net 2.0 information (Word). Function calls, loops, conditionals and the like.
The other one is base
SQL and T-SQL (Word). Selects, updates, loops, and conditional. It is pretty basic although it does have some 'GROUP BY' and 'HAVING' clauses in there.
I don't know how much use they would be except for beginners, but it could be nice to put on your cube wall for easy reference.
Labels: .NET, SQL
posted by Tom Becker at
|
