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 |
AskSQLTeam
Ask SQLTeam Question
0 Posts |
Posted - 2002-09-11 : 14:10:09
|
oki writes "Hi SQLTeam,I am new to MSSQL server (2 months junior). I am an old Oracle, Teradata dba. Now I am trying to port my Teradata datawarehouse and related applications, scripts to MSSQL 2000 server. So for 2 months, I try to collect any valuable info related for this project. Maybe I missed something but really I could' I find a sol'n and thus sent the following question to Andy. In case Andy can't receive or answer my urgent question, I also posted it here. I had modif?ed his article's script "Error handling in long-running batch jobs" for my project. In summary today I look for a way of getting rowcount etc. info through DMO. For instance:ALTER procedure p1 as-- SET XACT_ABORT ONset nocount offselect 1 print '[IKS: ' + cast(@@rowcount as char(9)) + ']'select 5 union select 4 print '[IKS: ' + cast(@@rowcount as char(9)) + ']'goand some VB code: Dim smessage As String SQL = "exec p1" Set odatabase = oSQLServer.Databases("production") odatabase.ExecuteWithResultsAndMessages2 SQL, smessage MsgBox (smessage)returns me null smessage if I remove "print ..." lines. So I had to use prints to return that info.>>>>>>>>>>>>>>>Hi Andy,I am an old Teradata, Oracle dba, but a new MSSQL dba candidate. I am porting a Teradata datawarehouse system to MSSQL. I want to develop a monitor system to run a list of batch scripts in order. I also want to capture errors, print messages, and rowcounts of each statement. So after a search, I found your article and slightly modified it. I plan to use it giving my procedures or scripts as parameter. Now my only problem is not to be able to log rowcounts without using "print @rowcount" after each statement in the script. I am searching for a method, option etc. to be able to log also those info as displayed by Query Analyzer tool without modifying original scripts. Besides rowcount, I would want to be informed and add any additional message, info available during script run.Sorry for my late question. I would appreciate any comment if possible.<<<<<<<<<<<<<<<<<<THIoki" |
|
AjarnMark
SQL Slashing Gunting Master
3246 Posts |
Posted - 2002-09-11 : 14:40:34
|
Oki,It seems to me this would be most easily returned by using OUTPUT Parameters in your stored procedure.ALTER procedure p1 @RowsAffect varchar(100) OUTPUTas -- SET XACT_ABORT ON set nocount off select 1 SET @RowsAffect = '[IKS: ' + cast(@@rowcount as char(9)) + ']' select 5 union select 4 SET @RowsAffect = @RowsAffect '[IKS: ' + cast(@@rowcount as char(9)) + ']' go |
|
|
robvolk
Most Valuable Yak
15732 Posts |
Posted - 2002-09-11 : 15:10:44
|
I agree with Mark's approach, it is far easier to get that information using his method, and is more reliable too. However, if you absolutely have to have this info using DMO methods, the QueryResults object has some properties that list the number of result sets returned (the ResultSets property), and they can be enumerated using the CurrentResultSet property. The QueryResults object also has a Rows property. Books Online has more details on these, under Contents/Building SQL Server Applications/SQL-DMO/Objects. |
|
|
oktayhg
Starting Member
2 Posts |
Posted - 2002-09-12 : 02:35:20
|
Hi all,Volk, Mark, thank you for your answers. First of all, I don't want to modify original code that will be executed. I used queryresults, but it seems returning only recordsets if any and corresponding rowcount. For example, an insert statement does not return any thing. Below I list my code. I look for your comments about the current one and of course my original question. Besides, any advice about transferring, porting data/applications from Teradata/Oracle to MSSQLServer will be appreciated. For example, I suffer from 01-01-1753 minimum date restriction on MSSQL while transfers. Thanks OKI Note: You can try the following code as create procedure p1 as -- SET XACT_ABORT ON set nocount off select 1 print '[IKS: ' + cast(@@rowcount as char(9)) + ']' select 5 union select 4 print '[IKS: ' + cast(@@rowcount as char(9)) + ']' go declare @p varchar(550)exec spi_BatchLog_deneme_3 'on exec p1 ', 146, null, @p outprint @pIt will return in batchlog: IKS for rowcounts, DKS for rows of queryresults if any. ALTER procedure spi_BatchLog_deneme_3@pSQL VARCHAR(8000),@pJobID INTEGER,@pComment VARCHAR(8000),@pDonusAciklama VARCHAR(1000) out--------------------------------------------------------------------------------------- Run the basic script-- This could be inside a stored procedure-------------------------------------------------------------------------------------asdeclare @rows integerDECLARE @pDonusDegeri INTEGER DECLARE @Status VARCHAR(255)DECLARE @oSQLServer INTEGERDECLARE @oDatabase INTEGERDECLARE @oQueryResults INTEGERDECLARE @CurrentDB VARCHAR(255)DECLARE @Return INTEGERDECLARE @SQL VARCHAR(8000)DECLARE @Source VARCHAR(255)DECLARE @Length INTEGER DECLARE @JobID INTEGERDECLARE @Error INTEGERDECLARE @ErrorMsg VARCHAR(255) SET @JobID = @pJobIDSET @pDonusDegeri = 0SET @Status = 'BASLADI'EXEC spi_BatchLog @JobID, Null, @pComment, @StatusBEGIN TRAN -- Create the SQLServer objectEXEC @Error = sp_OACreate 'SQLDMO.SQLServer2', @oSQLServer OUTIF @Error <> 0 GOTO OA_Error-- Set the login process to use NT AuthenticationEXEC @Error = sp_OASetProperty @oSQLServer, 'LoginSecure', -1IF @Error <> 0 GOTO OA_Error-- Connect to server using NT AuthenticationEXEC @Error = sp_OAMethod @oSQLServer, 'Connect', NULL, @@SERVERNAMEIF @Error <> 0 GOTO OA_Error-- Verify the connectionEXEC @Error = sp_OAMethod @oSQLServer, 'VerifyConnection', @Return OUTPUTIF @Error <> 0 GOTO OA_ErrorIF @Return = 0 GOTO OA_Error -- Set the database object to be the current database-- (We do this so we don't need to execute the SQL against the-- SQLServer object, which would require explicit DB prefixing)SELECT @CurrentDB = DB_NAME()SELECT @CurrentDB = 'Databases("' + RTRIM(@CurrentDB) + '")'EXEC @Error = sp_OAGetProperty @oSQLServer, @CurrentDB, @oDatabase OUTIF @Error <> 0 GOTO OA_Error -- Build the SQL string-- SET @SQL = 'EXECUTE spi_BatchLog ' + CONVERT(CHAR(12),@JobID) + ', ' + '''Message from Inside Transaction'''+ ', ' + ''' '''SET @SQL = @pSQL-- Execute the SQL (this will NOT be rolled back)-- We could use ExecuteImmediate here, but it doesn't return a result-- and we found while debugging that you really NEED thatSET @Length = LEN(@SQL)SET @ErrorMsg = '' -- Must initialize the @ErrorMsg stringEXEC @Error = sp_OAMethod @oDatabase, 'ExecuteWithResultsAndMessages2', @oQueryResults OUTPUT, @Command = @SQL , @Length = @Length, @Messages = @ErrorMsg OUTPUTIF @Error <> 0 GOTO OA_ErrorEXEC @Error = sp_OAGetProperty @oQueryResults, 'Rows', @Rows OUTIF @Error <> 0 GOTO OA_Errorset @pComment = '[DKS: ' + cast(@rows as char(9)) + ']'-- Destroy the objectsEXEC @Error = sp_OADestroy @oSQLServerEXEC @Error = sp_OADestroy @oDatabaseEXEC @Error = sp_OADestroy @oQueryResults GOTO DONE-----------------------------------------------OA_Error:ROLLBACK TRAN-- Get the error textEXEC sp_OAGetErrorInfo @oSQLServer, @Source OUT, @ErrorMsg OUTSELECT @ErrorMsg = CONVERT(CHAR(16), @Error) + ': ' + @ErrorMsg + ' (Source: ' + @Source + ')'SET @pDonusDegeri = @ErrorSET @pDonusAciklama = @ErrorMsg -- Write the error to the logSET @Status = 'HATALI_BITTI'EXEC spi_BatchLog @JobID, @ErrorMsg, @pComment, @StatusEXEC @Error = sp_OADestroy @oSQLServerEXEC @Error = sp_OADestroy @oDatabaseEXEC @Error = sp_OADestroy @oQueryResultsreturn @pDonusDegeri DONE:SET @Status = 'BASARILI_BITTI'SET @pComment = @pComment + replace(@ErrorMsg, '[Microsoft][ODBC SQL Server Driver][SQL Server]', '')SET @pComment = substring(@pComment, 1, charindex('[IKS]',@pComment) - 1)-- SET @pComment = @pComment + @ErrorMsgEXEC spi_BatchLog @JobID, NULL, @pComment, @StatusCOMMITSET @pDonusAciklama = @pCommentreturn @pDonusDegeriGO |
|
|
robvolk
Most Valuable Yak
15732 Posts |
Posted - 2002-09-12 : 09:50:45
|
quote: I used queryresults, but it seems returning only recordsets if any and corresponding rowcount. For example, an insert statement does not return any thing.
Well, that's because an INSERT operation isn't a query. You must grab the @@ROWCOUNT value immediately after the INSERT and put it into a variable, or SELECT @@ROWCOUNT immediately after. Then you can enumerate the QueryResults and get the row count for any operation. I'm pretty sure that's the only way you're going to get that kind of data.quote: For example, I suffer from 01-01-1753 minimum date restriction on MSSQL while transfers.
What data are you storing that actually uses dates earlier than that? If you don't have real data with those values, then this isn't a problem.One other thing:quote: First of all, I don't want to modify original code that will be executed.
That's a very unreasonable approach to take when porting an app from one system to another. There is little chance that you can pick something up line-for-line and bring it over and even get close to having it work correctly. If you slice up a loaf of bread, you will never get back the exact same loaf no matter how cleanly you do it. Trying to write an app that works everywhere without modification only compromises its performance on all platforms.Additionally, different products have different capabilities; if they didn't there would only be one database product in the world. You will do better to learn what SQL Server can do and use its strengths in your app. I'm not sure exactly what your app requires, but I do know that you can get row counts very easily without using SQL-DMO. |
|
|
oktayhg
Starting Member
2 Posts |
Posted - 2002-09-12 : 11:01:24
|
Hi Volk,In general I aggree with you. As in my code, I reached a sol'n anyway. My considerations are below:1. As I indicated in the title, I wanted to be able to grab rowcounts affected by each statement in any script or procedure. This script or procedure can be dynamically changed or provided by any body. As far as I know from some help search, it is indicated that Microsoft Utilities like Enterprise Manager are/can be developed using SQL-DMO. I think Ouery Analyzer also can be developed using SQL-DMO. So if I had developed my Query Analyzer, how could I get and those "1 rows deleted..." messages? Should I first modify original code then process it? This is my main consideration. Of course, some modifications are required and natural while portings, this is a general issue we encounter during everyday administration of multiplatform environments.2. Excuse me, but I saw this kind of restriction only on MSSQL platform. I think its root is Sybase. Progress, Teradata, Oracle all support this range of dates.How can't you save a historical date in your enterprise server? Should you use an sql server just for bank transactions? I don't find this as an acceptable reason?So I hope a way of my coding my query analyzer, whether using SQL-DMO or another way. Thank you for your comments, directions.regards,Oki |
|
|
robvolk
Most Valuable Yak
15732 Posts |
Posted - 2002-09-12 : 11:35:48
|
quote: I think Ouery Analyzer also can be developed using SQL-DMO.
As far as I know you can't modify Query Analyzer itself, you'd develop your own application. QA does not use SQL-DMO either, only Enterprise Manager does. Additionally, you can use ADO to work with SQL Server for pretty much any SQL command, if you are creating your own user interface.quote: 2. Excuse me, but I saw this kind of restriction only on MSSQL platform. I think its root is Sybase. Progress, Teradata, Oracle all support this range of dates.How can't you save a historical date in your enterprise server? Should you use an sql server just for bank transactions? I don't find this as an acceptable reason?
That was the point of my question: ARE YOU storing data that fits that date range or not? If you're not, and you don't anticipate the need, then it is NOT a restriction. That's like complaining about a restaurant that doesn't serve a type of food that you don't eat anyway. It does not help to complain about the restrictions of a database product that you will never encounter; and in any case, if that product doesn't do what you need, then don't use it. Oracle has plenty of restrictions too, if I have to use Oracle I work around them.As far as getting the row counts for all commands submitted to the server, why do you want to do this? Is it for logging purposes? I'm rather confident that using SELECT @@ROWCOUNT (NOT PRINT @@ROWCOUNT, do not use PRINT) will suffice. It might require pre-parsing the SQL statements that are passed to your application. You might also want to look at SQL Profiler, it can be configured to trace SQL commands and provide information on them. |
|
|
nr
SQLTeam MVY
12543 Posts |
Posted - 2002-09-13 : 03:27:29
|
The date range restriction is only a restriction of the datetime datatype. If you want to use value that won't fit in the field then use a different datatype which may take up more space depending on the accuracy you want.Note that historic dates are country dependent and tend to jump around a lot as calendars were corrected.For UK (and USA) ten or so days were dropped in 1752 which is why 1753 is the min date otherwise it would make date calculations and validation a bit odd - wonder what those other databases do about that.==========================================Cursors are useful if you don't know sql.DTS can be used in a similar way.Beer is not cold and it isn't fizzy. |
|
|
|
|
|
|
|