SQL Server 2005 ÖÐµÄ Multiple Active Result Set (MARS)(1)

¡¶SQL Server 2005 ÖÐµÄ Multiple Active Result Set (MARS)(1)¡·ÕªÒª£º ¼ò½é ËùÓÐ SQL Server Êý¾Ý·ÃÎÊÓ¦ÓóÌÐò±à³Ì½Ó¿Ú (API) ¶¼ÌṩÁËÒ»¸ö³éÏóÀ´±íʾ»á»°ºÍ»á»°ÖеÄÇëÇó¡£SQL Server 2000 ÒÔ¼°¸üÔçµÄ°æ±¾ÏÞÖÆ±à³ÌÄ£ÐÍ£¬ËüÒªÇóÈκÎʱºòÒ»¸ö¸ø¶¨µÄ»á»°ÖÐ×î¶àÖ»ÄÜÓÐÒ¡­

¼ò½é

ËùÓÐ SQL Server Êý¾Ý·ÃÎÊÓ¦ÓóÌÐò±à³Ì½Ó¿Ú (API) ¶¼ÌṩÁËÒ»¸ö³éÏóÀ´±íʾ»á»°ºÍ»á»°ÖеÄÇëÇó¡£SQL Server 2000 ÒÔ¼°¸üÔçµÄ°æ±¾ÏÞÖÆ±à³ÌÄ£ÐÍ£¬ËüÒªÇóÈκÎʱºòÒ»¸ö¸ø¶¨µÄ»á»°ÖÐ×î¶àÖ»ÄÜÓÐÒ»¸ö´ý¶¨µÄÇëÇó¡£Óм¸¸öÌæ´ú°ì·¨±»ÓÃÀ´½â¾öÕâÖÖÏÞÖÆ£¬ÔÚÕâÐ©Ìæ´ú°ì·¨ÖУ¬×î³£¼ûµÄ¿ÉÄܾÍÊÇ·þÎñÆ÷¶Ë¹â±ê¡£SQL Server 2005 ʵÏÖÁË Multiple Active Result Set (MARS)£¬Ëü½â³ýÁËÕâ¸öÔ¼Êø¡£±¾ÎĽéÉÜÁË MARS µÄÉè¼Æ¡¢½á¹¹ºÍÓïÒå±ä¸ü£¬ÒÔ¼°ÎªÁË´ÓÕâЩ¸Ä½øÖеõ½×î´óÊÕÒæ£¬Ó¦ÓóÌÐòÓ¦µ±×¢ÖØÊ²Ã´¡£

SQL Server 2000 Data Access Recap

Ŀǰ֧³ÖÓÃÓÚ¹¹½¨ SQL Server Ó¦ÓóÌÐòµÄÖ÷ÒªÊý¾Ý·ÃÎÊ API ÊÇ ODBC¡¢OLE-DB¡¢ADO ºÍ SqlClient .Net Provider¡£1ËüÃÇÈ«²¿¶¼Ìṩһ¸ö³éÏóÀ´±íʾһ¸öÖ¸Ïò·þÎñÆ÷µÄÒѽ¨Á¢Á¬½Ó£¬Í¬Ê±ÌṩÁíÍâÒ»¸ö³éÏóÀ´±íʾÔÚÕâ¸öÁ¬½ÓÖ®ÏÂÖ´ÐеÄÇëÇó¡£ÀýÈ磬SqlClient ʹÓà SqlConnection ºÍ SqlCommand ¶ÔÏ󣬶ø ODBC ÔòʹÓà SQL_HANDLE_DBC ÀàÐÍºÍ SQL_HANDLE_STMT ÀàÐ͵ľä±ú¡£

ËùÓз¢Ë͸ø SQL Server µÄÖ´ÐÐÇëÇó¶¼ÊǼ¸ºõÒÔÏÂÁ½ÖÖÐÎʽ֮һ£º1) Ò»×é T-SQL Óï¾ä£¬Í¨³£Ò²³ÆÎªÅú´¦Àí£¬»òÕß 2) ´æ´¢¹ý³Ì»òº¯ÊýµÄÃû³Æ£¬¼ÓÉϲÎÊýÖµ£¨¼ÙÈçºÏÊÊ£©¡£Çë×¢ÖØ£¬Ìá½»Ò»¸ö SELECT »ò DML Óï¾ä¸ø·þÎñÆ÷ÊÇÒ»¸öµ¥Óï¾äÅú´¦Àí£¬ÕâÊǵÚÒ»ÀàÇëÇóµÄÌØÀý¡£

ÔÚÈκÎÒ»ÖÖÇé¿öÏ£¬SQL Server ¶¼»áÖØÉêÅú´¦Àí»ò´æ´¢¹ý³ÌÖаüº¬µÄÓï¾ä£¬È»ºóÖ´ÐÐÕâЩÓï¾ä¡£Óï¾ä¿ÉÄÜ»áÉú³É½á¹û£¬Ò²¿ÉÄܲ»Éú³É½á¹û£¬²¢ÇÒÓï¾ä¿ÉÄÜ»áÏòµ÷ÓÃÕß·µ»Ø¸½¼ÓÐÅÏ¢£¬Ò²¿ÉÄܲ»·µ»Ø¡£

½á¹ûÖ÷ÒªÊÇÓÉ SELECT ºÍ FETCH Éú³ÉµÄ¡£SQL Server ͨ¹ý½«½á¹û·µ»Ø¸øµ÷ÓÃÕßÀ´Ö´ÐÐ SELECT Óï¾ä¡£ÕâÒâζ×Å£¬ÔÚ²éѯִÐÐÒýÇæ²úÉúÐеÄͬʱ£¬ÕâЩÐлᱻдÈëÍøÂç¡£¸üÈ·ÇеØËµ£¬Ëù²úÉúµÄÕâЩÐлᱻ¸´ÖƵ½Ô¤Ïȱ£ÁôµÄÍøÂ绺³åÇøÖУ¬È»ºó»º³åÇø»á±»·µ»Ø¸øµ÷ÓÃÕß¡£ÍøÂçдÈë²Ù×÷»á³É¹¦£¬²¢ÔÚ¿Í»§¶ËÇý¶¯³ÌÐò´ÓÍøÂçÖжÁȡʱÊÍ·ÅÒÑÓùýµÄ»º³åÇø¡£¼ÙÈç¿Í»§¶ËûÓÐÏûºÄ½á¹û£¬ÔÚÏàͬµãÉϵÄÍøÂçдÈë²Ù×÷½«»á±»×èÖ¹£¬·þÎñÆ÷ÖеÄÍøÂ绺³åÇø½«»á±»ÌîÂú£¬Ö´Ðоͻᱻ¹ÒÆð£¬µÈ´ý״̬ºÍÖ´ÐÐỊ̈߳¬Ö±µ½¿Í»§¶ËÇý¶¯³ÌÐò²¶×½¶ÁÈ¡¡£ÕâÖÖ²úÉú½á¹ûºÍ¼ìË÷½á¹ûµÄģʽͨ³£±»³ÆÎª¡°Ä¬ÈϽá¹û¼¯¡±£¬¸üÕýʽµÄÃû³ÆÔòÊÇ¡°Á÷Ë®Óαꡱ¡£

¸½¼ÓÐÅÏ¢Ò²¿ÉÄÜÒÔÆäËû·½Ê½£¨¿ÉÄÜûÓнá¹û·µ»Ø·½Ê½ÄÇôÃ÷ÏÔ£©±»·µ»Ø¸øµ÷ÓÃÕß¡£ÕâÖÖÇé¿ö°üÀ¨´íÎó¡¢¾¯¸æºÍÐÅÏ¢ÐÔÏûÏ¢¡£ËüÃÇ»òÕßͨ¹ý PRINT ºÍ RAISERROR Óï¾äÏÔʽ·µ»Ø£¬»òÕßͨ¹ýÓï¾äÖ´ÐÐÆÚ¼ä²úÉúµÄ¾¯¸æºÍ´íÎóÒþʽ·µ»Ø¡£Í¬ÑùµØ£¬µ± NOCOUNT ÉèÖÃÑ¡Ïî±»ÉèÖÃΪ OFF ʱ£¬SQL Server »á¶Ôÿ¸öÒÑÖ´ÐеÄÓï¾ä·¢ËÍÒ»¸ö¡°done row count¡±±ê¼Ç¡£ÕâÖÖ¸½¼ÓÐÅÏ¢Ò²¿ÉÄܵ¼ÖÂÍøÂçдÈ뻺³åÇø±»ÌîÂúºÍÖ´Ðб»¹ÒÆð¡£

ÕâÖÖ±³¾°Ê¹ÎÒÃÇ¿ÉÒÔÀí½â SQL Server 2000 ÒÔ¼°¸üÔç°æ±¾ÔÚÖ§³ÖÿÁ¬½Ó¶à¸ö´ý¶¨ÇëÇóʱµÄһЩ±à³ÌÄ£ÐÍÏÞÖÆ¡£

¡°Á¬½Ó·±Ã¦¡±

¶ÔÓÚ±¾ÎÄÖеÄʾÀý£¬ÎÒÃǽ«¼Ù¶¨ÒÔÏÂÕâÑùÒ»¸ö¼òµ¥µÄÇé¾³£ºÒ»¸öËÉÉ¢Á¬½ÓµÄÇåµ¥´¦ÀíϵͳʹÓá°Operations¡±±í×÷Ϊ¶ÓÁÐÀ´½ÓÊÕÀ´×ÔÆäËû×é¼þµÄÇëÇó£º

OPERATIONS

ÒÑ´¦Àí

λ

operation_id

int

Ö÷¼ü

operation_code

char(1)

'D' ¨C decrease inventory

'I' ¨C increase inventory

'R' ¨C reserve inventory

product_id

uniqueidentifier

ÊýÁ¿

bigint

ÎÒÃǼٶ¨Õâ¸ö×é¼þÖÎÀí×Ų»Í¬²úÆ·Ïߺ͹©¸øÉ̵ÄÇåµ¥£¬¶ø product_id ÔòÈ·¶¨ÒªÊ¹ÓÃÄĸö·þÎñÆ÷ºÍÊý¾Ý¿âÒÔ¼°ÈçºÎÖ´ÐÐÇëÇóµÄ²Ù×÷¡££¨Ò²¾ÍÊÇ˵£¬¼Ù¶¨²»¿ÉÄÜдÈëһЩ³É×é²Ù×÷À´´¦Àí¶ÓÁÐÖеÄËùÓÐÇëÇ󣩡£

Õâ¸ö×é¼þÔÚÒ»¸ö²åÈëµ½±íÖеÄËÉÉ¢´¦ÀíÇëÇóÖпªÊ¼ÔËÐУ¬²¢Ôڳɹ¦Íê³ÉÖ¸¶¨²Ù×÷ʱ½«ÕâЩÇëÇó±ê¼ÇΪÒÑ´¦Àí¡£

α´úÂëÀàËÆÈçÏÂËùʾ£º

while (1){Get all messages currently available in Operations table;For each message retrieved{ProcessMessage();Mark the message as processed;}}

Ç°ÃæÒ»¸öʹÓà odbc µÄ·½·¨ÀàËÆÈçÏÂËùʾ£¨ºöÂÔÁËһЩϸ½ÚºÍ´íÎó´¦Àí£©£º

SQLAllocHandle(SQL_HANDLE_STMT, hdbc1, &hstmt1);SQLAllocHandle(SQL_HANDLE_STMT, hdbc1, &hstmt2);while (true){ SQLExecDirect(hstmt1, (SQLTCHAR*)"select operation_id, operation_code, product_id, quantity from dbo.operations where processed=0", SQL_NTS); while (SQL_ERROR!=SQLFetch(hstmt1)) {ProcessOperation(hstmt1);SQLPrepare(hstmt2,  (SQLTCHAR*)"update dbo.operations set processed=1  where operation_id=?", SQL_NTS);SQLBindParameter(hstmt2, 1, SQL_PARAM_INPUT, SQL_C_SLONG,  SQL_INTEGER, 0, 0, &opid, 0, 0);SQLExecute(hstmt2); }}

µ«ÊÇ£¬³¢ÊÔÖ´ÐÐ hstmt2 »áµ¼Ö£º

[Microsoft][ODBC SQL Server Driver]Connection is busy with results for another hstmt.

ʹÓà SqlClient дÈëµ½ Microsoft Visual C# ÖеÄÏàͬÂß¼­ÀàËÆÈçÏÂËùʾ£º

SqlCommand cmd = conn.CreateCommand();SqlCommand cmd2 = conn.CreateCommand();cmd.CommandText= "select operation_id, operation_code, product_id, quantity  from dbo.operations where processed=0";cmd2.CommandText="update dbo.operations set processed=1  where operation_id=@operation_id";SqlParameter opid=cmd2.Parameters.Add("@operation_id", SqlDbType.Int);reader=cmd.ExecuteReader();while (reader.Read()){ ProcessOperation(); opid.Value=reader.GetInt32(0); // operation_id cmd2.ExecuteNonQuery();}

ͬÑùµØ£¬³¢ÊÔÖ´ÐдËÂß¼­»áµ¼Ö£º

InvalidOperationException, There is already an open DataReader associated with this Connection which must be closed first.

ÕâЩ´íÎóÊÇȱÉÙ MARS µÄ×îÖ±½Ó֤ʵ£»ÔÚÈκÎʱºò£¬Ò»¸ö¸ø¶¨µÄ SQL Server Á¬½ÓÖ®ÏÂ×î¶àÖ»ÄÜÓÐÒ»¸ö´ý¶¨ÇëÇó¡£

ÎÒÓÐÒâºöÂÔÁË OLEDB£¬ÒòΪËü»á²úÉúÂÔ΢Óе㲻ͬµÄÐÐΪ¡£


SQL Server 2005 ÖÐµÄ Multiple Active Result Set (MARS)(1)À´×ÔÍøÂ磬½ö¹©²Î¿¼¡£
ÄãµÄλÖ㺵çÄÔ¹ÊÕÏÍø >> Êý¾Ý¿â >> SQL Server >> SQL Server 2005 ÖÐµÄ Multiple Active Result Set (MARS)(1)