Tabular Data Stream: The Binding Between Client and SAP ASE

Post on 26-Jul-2015

191 views 2 download

Tags:

Transcript of Tabular Data Stream: The Binding Between Client and SAP ASE

(c) 2015 Independent SAP Technical User Group

Annual Conference, 2015

TDS Protocol Reference

TDS - Tabular Data StreamReference and information to assist in

diagnosing client/server problemsAuthor: Paul Vero

March, 2015

(c) 2015 Independent SAP Technical User Group

Annual Conference, 2015

ContentsIntroduction to TDS

VersionsPDF documents

TDS DocumentationCapture tools

RiboGuiProxSniffersSrv.logBuilt-in tracing

TokensLogin Simple select from execution to response, result set

FormatsRow DataParameters

Stored procedure calls with parameters

(c) 2015 Independent SAP Technical User Group

Annual Conference, 2015

Contents

Introduction to TDSVersionsPDF documents

TDS DocumentationCapture tools

RiboGuiProxSniffersSrv.log

TokensLogin Simple select from execution to response, result set

FormatsRow DataParameters

Stored procedure calls with parameters

(c) 2015 Independent SAP Technical User Group

Annual Conference, 2015

Introduction to TDS

• You always hear the Engineer or PSE say “Get me a TDS trace!”• “What the heck is that?”• Tabular Data Stream

• It’s a token based, application level protocol used to send requests and responses between clients and servers

• Relies on a connection oriented transport service• TCPIP provides such a transport

(c) 2015 Independent SAP Technical User Group

Annual Conference, 2015

Versions

• The TDS Specification has been around a long time• Started with 4.X (4.2)

• The earliest I’m aware of is TDS 4.0, 1988

• Current TDS version is 5.0• Released mid to late 90s• Revisions are labeled as 3.X

• Latest revision is 3.9• February 2007

(c) 2015 Independent SAP Technical User Group

Annual Conference, 2015

ContentsIntroduction to TDS

VersionsPDF documents

TDS DocumentationCapture tools

RiboGuiProxSniffersSrv.log

TokensLoginMessage Header Simple select from execution to response, result set

FormatsRow DataParameters

Stored procedure calls with parameters

(c) 2015 Independent SAP Technical User Group

Annual Conference, 2015

TDS documentation

• This is the internal TDS webpage:• http://www-ocsd/TDS/• Contains the current version:

• http://www-ocsd/TDS/specification/39/tds39.pdf• Previous and archived versions

• The specification is in PDF format

• Contains reference for every supported TDS token

(c) 2015 Independent SAP Technical User Group

Annual Conference, 2015

TDS documentation

• This section will provide additional information as it walks through the TDS specification document, tds39.pdf• This is a high level explanation of the sections• This is useful to understand the concept of a

client/server protocol• This presentation will not cover every chapter in the

specification• Guide to get you used to the document

(c) 2015 Independent SAP Technical User Group

Annual Conference, 2015

What uses TDS?

• Any client for ASE uses TDS• Think of it as the communicating protocol between

server (ASE) and client

• Supported clients:• Open Client/Server• ASE Data Access Products:

• ODBC, OLE DB, ADO.NET, jConnect

• Proxy servers and gateways:• ASE/CIS, DirectConnect, Replication Server, IQ

(c) 2015 Independent SAP Technical User Group

Annual Conference, 2015

TDS Model

SQLConnect();SQLExecute()SQLFetch();

ODBC Code

OD

BC

A

PI

TD

S/N

etwo

rk L

ayer

ODBC DriverTDS/Network Layer

TDS LOGIN record

User name: sa

Password: []

Charset: cp850

(c) 2015 Independent SAP Technical User Group

Annual Conference, 2015

Sample TDS Session

• When client is going to connect to ASE it first requests a transport connection (TCPIP) to the ASE server.

• Client then sends the login record to start the dialog.

• ASE responds with an acknowledgement token (TDS_LOGINACK) along with a completion token (TDS_DONE).• When this occurs, it means the ASE

accepts the dialog with this client

(c) 2015 Independent SAP Technical User Group

Annual Conference, 2015

Sample TDS Session

• With the established dialog the client is now ready to send SQL statements to the ASE.• To send a SELECT statement client sends

it in TDS_LANGUAGE token.• ASE executes the query and sends the

following:• Column description of result set• Data rows follow this• TDS_DONE completion packet, with row count

is the last thing sent

(c) 2015 Independent SAP Technical User Group

Annual Conference, 2015

Sample TDS Session

Login request

Client Server (ASE)

hostname: asehostUsername: tdsuserPassword: tdspwdtds version: 5.0Application: ado.net

Login request

TDS_LOGINACK

TDS_DONE

(c) 2015 Independent SAP Technical User Group

Annual Conference, 2015

Sending TDS request

Language Request

Client Server (ASE)

- Execute: Select * from authors- Process the rows when Received- Stop processing when Last row is received

TDS_LANGUAGE

TDS_ROWFMT

TDS_DONE

TDS_ROW, TDS_ROW, …

(c) 2015 Independent SAP Technical User Group

Annual Conference, 2015

Protocol Data Units - PDUs

PDU is used to contain the request (client) and response (server)

The request/response might span several PDUsSize of the PDU is decided between client and server

during the login time (dialog establishment)PDU contains header and usually data

(c) 2015 Independent SAP Technical User Group

Annual Conference, 2015

• PDU Header

• PDU header contains information about the size and contents of the PDU as well as an indication if this is the last PDU in a request/response

• Described in the Message Buffer Header reference page• TDS is half-duplex

• Client writes complete request• Then it reads complete response from server• None are intermixed and multiple requests can’t

be outstanding (active results pending)

(c) 2015 Independent SAP Technical User Group

Annual Conference, 2015

PDU Header

(c) 2015 Independent SAP Technical User Group

Annual Conference, 2015

PDU Header

• Before going further there are some tools to be discussed in detail later, used to format PDUs in readable format• RAW format displays data similar to that

found in sniffer trace• Use ASE traceflags on command-line:

• 4001, 4013, 4034, 4035 and 4036• 4013 prints out the login record contents

• Information goes to stdout so might want to use tee

• Formated output with RIBO• Java based TDS packet gateway tool

(c) 2015 Independent SAP Technical User Group

Annual Conference, 2015

Raw TDS from ASER STRMBUF: socket 5 status 0x20000 size 2048 left 504TDS type TDSLOGIN (2) status 0 len 512 chan 0 pack 0 win 02020AAA0 ( 0): 02000002 00000000 50564552 4f585000 00000000 ........PVEROXP.....2020AAB4 ( 20): 00000000 00000000 00000000 00000000 00000773 ...................s2020AAC8 ( 40): 61000000 00000000 00000000 00000000 00000000 a...................2020AADC ( 60): 00000000 00000000 00020000 00000000 00000000 ....................2020AAF0 ( 80): 00000000 00000000 00000000 00000000 00000000 ....................2020AB04 ( 100): 00353836 34000000 00000000 00000000 00000000 .5864...............2020AB18 ( 120): 00000000 00000000 00000004 0301060a 09010100 ....................2020AB2C ( 140): 00000000 00000000 6973716c 00000000 00000000 ........isql........2020AB40 ( 160): 00000000 00000000 00000000 00000000 00000472 ...................r2020AB54 ( 180): 69626f00 00000000 00000000 00000000 00000000 ibo.................2020AB68 ( 200): 00000000 00000000 00040000 00000000 00000000 ....................2020AB7C ( 220): 00000000 00000000 00000000 00000000 00000000 ....................2020AB90 ( 240): 00000000 00000000 00000000 00000000 00000000 ....................2020ABA4 ( 260): 00000000 00000000 00000000 00000000 00000000 ....................2020ABB8 ( 280): 00000000 00000000 00000000 00000000 00000000 ....................2020ABCC ( 300): 00000000 00000000 00000000 00000000 00000000 ....................2020ABE0 ( 320): 00000000 00000000 00000000 00000000 00000000 ....................2020ABF4 ( 340): 00000000 00000000 00000000 00000000 00000000 ....................2020AC08 ( 360): 00000000 00000000 00000000 00000000 00000000 ....................2020AC1C ( 380): 00000000 00000000 00000000 00000000 00000000 ....................2020AC30 ( 400): 00000000 00000000 00000000 00000000 00000000 ....................2020AC44 ( 420): 00000000 00000000 00000000 00000000 00000000 ....................2020AC58 ( 440): 00000000 00000000 00000000 00000000 00000000 ....................2020AC6C ( 460): 00000000 00020500 00004354 2d4c6962 72617279 ..........CT-Library2020AC80 ( 480): 0a0f0000 00000d11 00735f65 6e676c69 73680000 .........s_english..2020AC94 ( 500): 00000000 00000000 00000000 ............

Hostname

TDS Version 5.0.0.0

Application

(c) 2015 Independent SAP Technical User Group

Annual Conference, 2015

Login record from ASE errorlog

This traceflag, 4013 is useful to get the contents of the login record:

00:00000:00017:2008/04/10 22:27:26.30 server Received LOGINRECLOGINREC at 0x20AF7D88 host=`PVEROXP' user=`sa' hostproc=`5864' int2=3 int4=1 char=6 flt=10 date=9 usedb=1 dmpld=1 interface=0 netconn_type=0 appname=`isql' servername=`ribo' tds_vers=(5.0.0.0) progname=`CT-Library' prog_vers=(15.0.0.0) noshort=0 flt4=13 date4=17 language=`' setlang=0 SECURITY: hier=0 e2e option: 0x00 db bulk reserved: 0x00 HA: ssn option: 0x08 ssn handle:(0x00, 0x00, 0x00, 0x00, 0x00, 0x00) UNUSED: slunused:(0x00) role=0 charset=`iso_1' setcharset=0 packetsize=`512'00:00000:00017:2008/04/10 22:27:26.30 server login: sa PVEROXP, spid: 17, kpid: 1245203 (0x130013)

(c) 2015 Independent SAP Technical User Group

Annual Conference, 2015

TDS output from RIBOCapture Record Header Source [4]: REQUEST (0x00000001) Length [4]: 615

PDU Header TDS Packet Type [1]: BUF_LOGIN (0x02) Status [1]: BUFSTAT_BEGIN (0x00) Length [2]: 512 Channel [2]: 0 Packet No. [1]: 0 Window [1]: 0

PDU Header TDS Packet Type [1]: BUF_LOGIN (0x02) Status [1]: BUFSTAT_EOM (0x01) Length [2]: 103 Channel [2]: 0 Packet No. [1]: 0 Window [1]: 0

(c) 2015 Independent SAP Technical User Group

Annual Conference, 2015

PDU Data

• PDUs usually include some data• Control PDUs don’t contain data

• Only header

• Request and Response PDUs contain TDS tokens• Tokens describe the request/response• Data is exchanged so the client and server can

complete the request/response cycle

(c) 2015 Independent SAP Technical User Group

Annual Conference, 2015

Client PDUs - Requests

Dialog establishment informationLanguage commandCursor commandDatabase Remote Procedure CallAttentionsDynamic SQL commandMessage command

(c) 2015 Independent SAP Technical User Group

Annual Conference, 2015

Client PDU: Dialog Establishment

• Create a transport connection• This is a low level network function

• TCPIP and socket establishment• Send Login record

• Credentials and properties• Send Capability data stream

• What can I (client) do, what can’t I do• What can and can’y you (the Server) do

• Authentication handshaking• Password encryption

• Read login acknowledgement

(c) 2015 Independent SAP Technical User Group

Annual Conference, 2015

Client PDU: Language Commands

• Send a SQL Command to the ASE• TDS_LANGUAGE token is used to send the command• Command may span multiple PDUs

• Limited by length field in the TDS_LANGUAGE token

(c) 2015 Independent SAP Technical User Group

Annual Conference, 2015

Client PDU: Cursor Commands

• There are two ways to send cursor commands• Language commands

• TDS_LANGUAGE• Send to ASE using Cursor T-SQL commands• Other servers require to parse language and be able

to implement the cursor language

• Cursor TDS tokens• ANSI specified cursor operations• Native token support• Efficient by eliminating parsing sequence

• TDS_CUR* tokens

(c) 2015 Independent SAP Technical User Group

Annual Conference, 2015

Client PDU: Remote Procedure Calls (RPC)

• Client sends TDS_DBRPC token• Binary stream containing:

• Rpc NAME• Options• Parameters

• No intermixing with SQL commands or other RPC commands

• Uses additional tokens to define the parameters and to send parameter values

(c) 2015 Independent SAP Technical User Group

Annual Conference, 2015

Client PDU: Attention

The client sends an attention signal to the server to cancel its current requestClient sends attention to serverClient continues to read Client discards the data read after sending attentionServer acknowledges the attention and now

everyone is happy

(c) 2015 Independent SAP Technical User Group

Annual Conference, 2015

Client PDU: Dynamic SQL

The client sends TDS_DYNAMIC or TDS_DYNAMIC2 data stream to execute dynamic SQL on the server.Stream indicates various functionality:

PrepareExecuteDeallocateArguments included?SQL Statement and identification

(c) 2015 Independent SAP Technical User Group

Annual Conference, 2015

Server PDU: Response

Dialog Establishment acknowledgementLogin request is received

Row resultsReturn status from proceduresReturn parametersResponse completionError informationAttention acknowledgementCursor statusMessage responses

(c) 2015 Independent SAP Technical User Group

Annual Conference, 2015

On to the gory details

• The TDS specification documentation contains details on various topics

• Read these when you’re ready to learn the topic, like cursors, security, etc.

• Contains descriptions and diagrams of the data flow

(c) 2015 Independent SAP Technical User Group

Annual Conference, 2015

ContentsIntroduction to TDS

VersionsPDF documents

TDS Documentation

Capture toolsRiboGuiProxSniffersSrv.logBuilt-in tracing

TokensLoginMessage Header Simple select from execution to response, result set

FormatsRow DataParameters

Stored procedure calls with parameters

(c) 2015 Independent SAP Technical User Group

Annual Conference, 2015

Capture Tools

• Capture tools gather the TDS data stream into a file• Useful for troubleshooting purposes• Everyone asks for TDS trace

• Verify activity• Determine problems• Isolate whether client or server side

(c) 2015 Independent SAP Technical User Group

Annual Conference, 2015

Capture ToolsRibo

Most commonFormattedIncluded in SDK and ASE installs

GuiProxUseful when needing timestampsRaw output

SniffersUsed when unable to get others to workNecessary if issues with TCP/IP protocol

ASE TDSTrace options captures raw TDS between server and client

srv.logOpen Server logRaw TDSDirectConnect, DCO

(c) 2015 Independent SAP Technical User Group

Annual Conference, 2015

Ribo

• Ribo is most common tool • Java based and requires these env variables:

• set RIBO_HOME=%SYBASE%\jutils-2_0\ribo• set JAVA_HOME=C:\Java\jdk\jdk1.5.0_09

• Just make sure this points to a jvm

• Start up with arguments• ribo -l 9999 -s %1 -p %2 -gui -c cat -t -f devfilter.x

(c) 2015 Independent SAP Technical User Group

Annual Conference, 2015

Ribo Gui

Startup Ribo and this is what you get

(c) 2015 Independent SAP Technical User Group

Annual Conference, 2015

Ribo Gui

• Preferences provide options

• Capture file prefix

• Translation filter

• Option to translate

• Option to display in a window• Careful as this

is resource intensive

(c) 2015 Independent SAP Technical User Group

Annual Conference, 2015

Ribo Gui: Display in Window

(c) 2015 Independent SAP Technical User Group

Annual Conference, 2015

Ribo is a TDS gateway

Client WorkstationHost: RainConnect to Ribo Host

ASE ServerHost: SnowPort: 1502

Ribo Host: RainPort: 9999Connects to Snow,1502Ribo –l 9999 –s Snow –p 1502 –gui …

(c) 2015 Independent SAP Technical User Group

Annual Conference, 2015

RIBO environment

Windows example:

set RIBO_HOME=c:\sap\syb157\jutils-3_0\riboset JAVA_HOME=C:\sap\syb157\jre64set PATH=%JAVA_HOME%\bin;%PATH%c:cd %RIBO_HOME%

(c) 2015 Independent SAP Technical User Group

Annual Conference, 2015

Sample RIBO Output

Connect to ASE 15.0.2Issue select @@versionIssue select * from tds_table

Table has int, varchar, decimal and datetimeCall stored procedure

sp_test @a, @b@b is output parameter

(c) 2015 Independent SAP Technical User Group

Annual Conference, 2015

Select @@version

(c) 2015 Independent SAP Technical User Group

Annual Conference, 2015

Ribo trace walkthrough: Login Record

Login Record; fixed length. Host Name [30]: "PVEROXP" Host Name Length [1]: 7 User Name [30]: "sa" User Name Length [1]: 2 Password [30]: "" Password Length [1]: 0 Host Process [30]: "3124" Host Process Length [1]: 4 Byte Ordering - int2 [1]: 3 Byte Ordering - int4 [1]: 1 Character Encoding [1]: 6 Float Format [1]: 10 Date Format [1]: 9 lusedb [1]: 0x01 ldmpld [1]: 1 linterfacespare [1]: 0x00

(c) 2015 Independent SAP Technical User Group

Annual Conference, 2015

Login Record Dialog Type [1]: 0 lbufsize [1]: 0 spare [3]: 0x000000 Application Name [30]: "isql" Application Name Length [1]: 4 Service Name [30]: "ribo" Service Name Length [1]: 4 Remote Passwords [255]: <universal>/<null> Remote Passwords Length [1]: 2 TDS Version [4]: 5.0.0.0 Prog Name [30]: "CT-Library" Prog Name Length [1]: 10 Prog Version [4]: 15.0.0.0 Convert Shorts [1]: 0 4-byte Float Format [1]: 13 4-byte Date Format [1]: 17

(c) 2015 Independent SAP Technical User Group

Annual Conference, 2015

Login Record

Language [30]: "" Language Length [1]: 0 Notify when Changed [1]: 0 Old Secure Info [2]: 0x0000 Secure Login Flags [1]: UNUSED (0x00) Bulk Copy [1]: 0 HA Login Flags [1]: 0x08 HA Session ID [6]: 0x000000000000 Spare [2]: 0x0000 Character Set [30]: "iso_1" Character Set Length [1]: 5 Notify when Changed [1]: 0 Packet Size [6]: 512 Packet Size Length [1]: 3

(c) 2015 Independent SAP Technical User Group

Annual Conference, 2015

CapabilitiesCAPABILITY Token (0xE2); variable length. Length [2]: 28 Type [1]: CAP_REQUEST Mask [12]: 0x00 (00000000): (MULTI_REQUESTS), (REQ_MIGRATE), (REQ_UNUSED) 0xE9 (11101001): REQ_DBRPC2, REQ_CURINFO3, DATA_XML, (REQ_BLOB_NCHAR_16), REQ_LARGEIDENT, (DATA_SINT1), (CAP_CLUSTERFAILOVER), DATA_UNITEXT 0xB5 (10110101): REQ_SRVPKTSIZE, (CSR_KEYSETDRIVEN), CSR_SEMISENSITIVE, CSR_INSENSITIVE, (CSR_SENSITIVE), CSR_SCROLL, (DATA_INTERVAL), DATA_TIME 0x87 (10000111): DATA_DATE, (BLOB_NCHAR_SCSU), (BLOB_NCHAR_8), (BLOB_NCHAR_16), (IMAGE_NCHAR), DATA_NLBIN, CUR_IMPLICIT, DATA_UINTN 0xE8 (11101000): DATA_UINT8, DATA_UINT4, DATA_UINT2, (REQ_RESERVED2), WIDETABLE, (DATA_COLUMNSTATUS), (OBJECT_BINARY), (REQ_RESERVED1) 0x3B (00111011): (OBJECT_CHAR), (OBJECT_JAVA1), DOL_BULK, DATA_VOID, DATA_INT8, (DATA_BITN), DATA_FLTN, PROTO_DYNPROC 0x61 (01100001): (PROTO_DYNAMIC), DATA_BOUNDARY, DATA_SENSITIVITY, (REQ_URGEVT), (PROTO_BULK), (PROTO_TEXT), (CON_LOGICAL), CON_INBAND 0x7F (01111111): (CON_OOB), CSR_MULTI, CSR_REL, CSR_ABS, CSR_LAST, CSR_FIRST, CSR_PREV, DATA_MONEYN 0xFF (11111111): DATA_DATETIMEN, DATA_INTN, DATA_LBIN, DATA_LCHAR, DATA_DEC, DATA_IMAGE, DATA_TEXT, DATA_NUM 0xFF (11111111): DATA_FLT8, DATA_FLT4, DATA_DATE4, DATA_DATE8, DATA_MNY4, DATA_MNY8, DATA_VBIN, DATA_BIN 0xFF (11111111): DATA_VCHAR, DATA_CHAR, DATA_BIT, DATA_INT4, DATA_INT2, DATA_INT1, REQ_PARAM, REQ_MSG 0xE6 (11100110): REQ_DYNF, REQ_CURSOR, REQ_BCP, (REQ_MSTMT), (REQ_EVT), REQ_RPC, REQ_LANG, (NONE)

Type [1]: CAP_RESPONSE

Mask [12]: 0x00 (00000000): (RES_NODATA_XML), (NO_SRVPKTSIZE), (RES_NOBLOB_NCHAR_16), (RES_NOLARGEIDENT) 0x00 (00000000): (DATA_NOSINT1), (DATA_NOUNITEXT), (DATA_NOINTERVAL), (DATA_NOTIME), (DATA_NODATE), (BLOB_NONCHAR_SCSU), (BLOB_NONCHAR_8), (BLOB_NONCHAR_16) 0x00 (00000000): (IMAGE_NONCHAR), (DATA_NONLBIN), (NO_WIDETABLES), (DATA_NOUINTN), (DATA_NOUINT8), (DATA_NOUINT4), (DATA_NOUINT2), (RES_RESERVED1) 0x02 (00000010): (OBJECT_NOBINARY), (DATA_NOCOLUMNSTATUS), (OBJECT_NOCHAR), (OBJECT_NOJAVA1), (DATA_NOINT8), (RES_NOSTRIPBLANKS), RES_NOTDSDEBUG, (DATA_NOBOUNDARY) 0x00 (00000000): (DATA_NOSENSITIVITY), (PROTO_NOBULK), (PROTO_NOTEXT), (CON_NOINBAND), (CON_NOOOB), (DATA_NOMONEYN), (DATA_NODATETIMEN), (DATA_NOINTN) 0x00 (00000000): (DATA_NOLBIN), (DATA_NOLCHAR), (DATA_NODEC), (DATA_NOIMAGE), (DATA_NOTEXT), (DATA_NONUM), (DATA_NOFLT8), (DATA_NOFLT4) 0x00 (00000000): (DATA_NODATE4), (DATA_NODATE8), (DATA_NOMNY4), (DATA_NOMNY8), (DATA_NOVBIN), (DATA_NOBIN), (DATA_NOVCHAR), (DATA_NOCHAR)

0x00 (00000000): (DATA_NOBIT), (DATA_NOINT4), (DATA_NOINT2), (DATA_NOINT1), (RES_NOPARAM), (RES_NOEED), (RES_NOMSG), (NONE)

(c) 2015 Independent SAP Technical User Group

Annual Conference, 2015

GuiProx

• Java gateway similar to Ribo in ways• Internal tool and provided to customers under specific

circumstances• Raw TDS output• Contains response and “think” times• Timestamps• Adjustable log size

(c) 2015 Independent SAP Technical User Group

Annual Conference, 2015

GuiProx[2014-03-10 12:48:52.124] Listening on port : 6001[2014-03-10 12:48:52.124] Server host is : 10.168.131.204[2014-03-10 12:48:52.124] Server port is : 1570[2014-03-10 12:48:52.124] Hex dump filter : true[2014-03-10 12:48:52.124] Sql filter : true[2014-03-10 12:48:52.124] TimeStamp entries : true[2014-03-10 12:48:52.134] Lilo dump filter : true[2014-03-10 12:48:52.134] Gui display window : false[2014-03-10 12:48:52.134] SSL Debugging : false[2014-03-10 12:48:52.134] Capture Tds : true[2014-03-10 12:48:52.134] Log Sql to file : false[2014-03-10 12:48:52.134] **** _sendDelay set to 0 millisecs[2014-03-10 12:48:52.134] **** _recvDelay set to 0 millisecs[2014-03-10 12:48:52.134] **** _cancelDelay set to false[2014-03-10 12:48:54.764] Thread-4: Opening socket to Server [2014-03-10 12:48:54.764] Thread-4: Tds Logging to file : cap0.tds

(c) 2015 Independent SAP Technical User Group

Annual Conference, 2015

GuiProx[2014-03-10 12:48:54.764] Thread-4: Client->Server: read 512 from client[2014-03-10 12:48:54.764] 00000000: 02 00 02 00 00 00 00 00 42 4a 43 4e 30 30 35 32 ........BJCN005200000010: 36 31 32 37 41 00 00 00 00 00 00 00 00 00 00 00 6127A...........00000020: 00 00 00 00 00 00 0d 73 61 00 00 00 00 00 00 00 .......sa.......00000030: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................00000040: 00 00 00 00 00 02 73 65 63 72 65 74 00 00 00 00 ......secret....00000050: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................00000060: 00 00 00 00 06 35 39 32 00 00 00 00 00 00 00 00 .....592........00000070: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................00000080: 00 00 00 03 03 01 06 0a 09 01 01 00 00 00 00 00 ................00000090: 00 00 00 00 69 73 71 6c 00 00 00 00 00 00 00 00 ....isql........000000a0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................000000b0: 00 00 04 67 75 69 70 72 6f 78 00 00 00 00 00 00 ...guiprox......000000c0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................000000d0: 00 07 00 06 73 65 63 72 65 74 00 00 00 00 00 00 ....secret......000000e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................*000001d0: 00 08 05 00 00 00 43 54 2d 4c 69 62 72 61 72 79 ......CT-Library000001e0: 0a 0f 07 00 0c 00 0d 11 00 73 5f 65 6e 67 6c 69 .........s_engli000001f0: 73 68 00 00 00 00 00 00 00 00 00 00 00 00 00 00 sh.............. [2014-03-10 12:48:54.764] Thread-4: Client->Server: read 107 from client[2014-03-10 12:48:54.774] 00000000: 02 01 00 6b 00 00 00 00 00 00 00 00 00 00 00 00 ...k............00000010: 00 00 00 00 08 00 00 00 00 00 00 00 00 69 73 6f .............iso00000020: 5f 31 00 00 00 00 00 00 00 00 00 00 00 00 00 00 _1..............00000030: 00 00 00 00 00 00 00 00 00 00 00 05 00 35 31 32 .............51200000040: 00 00 00 03 00 00 00 00 e2 20 00 01 0e 01 3c e2 ......... ....<.00000050: f9 b5 87 ea bb 6d 7f ff ff ff fe 02 0e 00 00 00 .....m..........00000060: 00 00 18 60 00 00 02 68 00 00 00 ...`...h... [2014-03-10 12:48:54.774] Thread-5: Server->Client: packetSize set to 2048

[2014-03-10 12:48:54.784] Thread-5: Server->Client: read 166 from server. response time was 9.327

(c) 2015 Independent SAP Technical User Group

Annual Conference, 2015

Network Sniffers

• Most operating systems contain built-in sniffers• tcpdump (Linux)• snoop (Solaris)

• Wireshark very popular and used to view captures from other sniffer apps

• Learn TCP/IP to understand the packets

(c) 2015 Independent SAP Technical User Group

Annual Conference, 2015

The srv.log from Open ServerMay 30 18:01:01 2013: Sybase Server-Library/15.7/P-EBF21007-21006 SP100/X64/BUILD1570-026/OPT/Sun Mar 24 08:34:18 2013May 30 18:01:01 2013: Sybase Client-Library/15.7/P-EBF21006 SP100/X64/BUILD1570-026/OPT/Sun Mar 24 08:32:57 2013

spid 6 - read: login, not eom, len=512, chan=0, pack=0, win=0, client

0x424a 0x434e 0x3030 0x3532 0x3631 0x3237 0x4100 0x0000 | BJCN00526127A

0x0000 0x0000 0x0000 0x0000 0x0000 0x0000 0x0000 0x0d73 | s

0x6100 0x0000 0x0000 0x0000 0x0000 0x0000 0x0000 0x0000 | a

0x0000 0x0000 0x0000 0x0000 0x0000 0x0000 0x0002 0x7365 | se

0x6372 0x6574 0x0000 0x0000 0x0000 0x0000 0x0000 0x0000 | cret

0x0000 0x0000 0x0000 0x0000 0x0000 0x0000 0x0631 0x3033 | 103

0x3532 0x0000 0x0000 0x0000 0x0000 0x0000 0x0000 0x0000 | 52

0x0000 0x0000 0x0000 0x0000 0x0000 0x0005 0x0301 0x060a |

0x0901 0x0100 0x0000 0x0000 0x0000 0x0000 0x6973 0x716c | isql

0x0000 0x0000 0x0000 0x0000 0x0000 0x0000 0x0000 0x0000 |

0x0000 0x0000 0x0000 0x0000 0x0000 0x0463 0x746f 0x7331 | ctos1

0x3537 0x3000 0x0000 0x0000 0x0000 0x0000 0x0000 0x0000 | 570

0x0000 0x0000 0x0000 0x0000 0x0008 0x0006 0x7365 0x6372 | secr

0x6574 0x0000 0x0000 0x0000 0x0000 0x0000 0x0000 0x0000 | et

0x0000 0x0000 0x0000 0x0000 0x0000 0x0000 0x0000 0x0000 |

0x0000 0x0000 0x0000 0x0000 0x0000 0x0000 0x0000 0x0000 |

0x0000 0x0000 0x0000 0x0000 0x0000 0x0000 0x0000 0x0000 |

0x0000 0x0000 0x0000 0x0000 0x0000 0x0000 0x0000 0x0000 |

0x0000 0x0000 0x0000 0x0000 0x0008 0x0500 0x0000 0x4354 | CT

0x2d4c 0x6962 0x7261 0x7279 0x0a0f 0x0700 0x0a00 0x0d11 | -Library

0x0073 0x5f65 0x6e67 0x6c69 0x7368 0x0000 0x0000 0x0000 | s_english

0x0000 0x0000 0x0000 0x0000 0x.... 0x.... 0x.... 0x.... |

===========================================================================

(c) 2015 Independent SAP Technical User Group

Annual Conference, 2015

Open Client debug variableC:\...\Atlanta\TDS>set SYBOCS_DEBUG_FLAGS=CS_DBG_PROTOCOL

C:\...\Atlanta\TDS>isql -Usa -Psecret -Spvw71572 -Dodbc

1> select * from tds_table

2> go

c1 c2 c3 c4

----------- -------------------- ------------- -------------------------------

1 TDS_LANGUAGE 2.1000 Mar 8 2015 9:56PM

2 TDS_DBRPC 14.6000 Mar 8 2015 9:56PM

3 TDS_CURDECLARE 8.6100 Mar 8 2015 9:56PM

4 TDS_DYNAMIC 14.7000 Mar 8 2015 9:56PM

5 TDS_ROW 13.1000 Mar 8 2015 9:56PM

(5 rows affected)

1> quit

Directory of C:\...\Atlanta\TDS

03/10/2015 10:44 PM 2,104 capF6BF.tmp

(c) 2015 Independent SAP Technical User Group

Annual Conference, 2015

Open Client debug variable

Run it through RIBO:

You can run the Ribo utility on the tds file to format in text format.

You can use a script:

ribo %1\%2.tds %1\%2.txt

mv or rename the *.tmp file to *.tds

In this case

ribo C:\...\Atlanta\TDS capF6BF.tds

Creates capF6BF.txt file

You can view file in editor to check the TDS

(c) 2015 Independent SAP Technical User Group

Annual Conference, 2015

Protocol Capture

• Drivers now have built-in TDS trace generator• Create in same TDS format as RIBO• Use RIBO to format into Text

• jConnect: PROTOCOL_CAPTURE• One thread/one connection• Use RIBO for multi-thread/connections

• ASE ADO.NET and ODBC• protocolcapture=filename.tds• Appends pid and thread/connection number

• Starts at 0

(c) 2015 Independent SAP Technical User Group

Annual Conference, 2015

ContentsIntroduction to TDS

VersionsPDF documents

TDS DocumentationCapture tools

RiboGuiProxSniffersSrv.log

Tokens and FlowTDS_ENVCHANGE, EED, LANGUAGE, etcSimple select from execution to response, result set

FormatsRow DataParameters

Stored procedure calls with parameters

(c) 2015 Independent SAP Technical User Group

Annual Conference, 2015

TDS Tokens

• TDS Tokens are the containers of the activity and information• Token expresses what it does

• Language, rpc, cursor, dynamic• Is it data, message, or something else?

• Data portion contains the information• Data from server response• Format information for parameters and fields• Messages, warnings and errors• Other forms of status

(c) 2015 Independent SAP Technical User Group

Annual Conference, 2015

Environment Change

• TDS_ENVCHANGE (0xE3)• The token contains environment change information• Items that can change, based on ASE defaults and client

specified• Current database• Charset• Language• Packet size

(c) 2015 Independent SAP Technical User Group

Annual Conference, 2015

Environment Change - TDS_ENVCHANGE (0xE3)

ENVCHANGE Token (0xE3); variable length.Length [2]: 13Type [1]: ENV_DB (0x01)Length of New Value [1]: 4New Value [4]: “odbc"Length of Old Value [1]: 6Old Value [6]: "master"

(c) 2015 Independent SAP Technical User Group

Annual Conference, 2015

Environment Change – use database exchange

LANGUAGE Token (0x21); variable length. Length [4]: 10 Status [1]: UNUSED (0x00) Text Length [0]: [9] Text [9]: "use odbc"

Capture Record Header Source [4]: RESPONSE (0x00000002) Length [4]: 101

PDU Header TDS Packet Type [1]: BUF_RESPONSE (0x04) Status [1]: BUFSTAT_EOM (0x01) Length [2]: 101 Channel [2]: 0 Packet No. [1]: 0 Window [1]: 0

ENVCHANGE Token (0xE3); variable length. Length [2]: 13 Type [1]: ENV_DB (0x01) Length of New Value [1]: 4 New Value [4]: "odbc" Length of Old Value [1]: 6 Old Value [6]: "master"

(c) 2015 Independent SAP Technical User Group

Annual Conference, 2015

Environment Change – use database exchange

EED Token (0xE5); variable length. Length [2]: 65 Message Number [4]: 5701 Message State [1]: 1 Message Class [1]: 10 SQL State Length [1]: 5 SQL State [5]: "ZZZZZ" Status [1]: NO_EED (0x00) Transaction State [2]: TDS_TRAN_SUCCEED (0x0001) Message Length [2]: 36 Message Text [36]: "Changed database context to 'odbc'." Server Name Length [1]: 8 Server Name [8]: "pvxp1253" Stored Proc. Name Length [1]: 0 Line Number [2]: 1

DONE Token (0xFD); fixed length. Length [0]: [8] Status [2]: DONE_FINAL (0x0000) TranState [2]: TDS_TRAN_PROGRESS (0x0002) Count (unused) [4]: 0

(c) 2015 Independent SAP Technical User Group

Annual Conference, 2015

TDS_LANGUAGE

• Sends SQL statement to the ASE as a language command• Think of the command as what you’d send

via ISQL• SELECT * FROM authors• INSERT INTO table1 values (1, ‘a’, 12.3)

• Simple token• Length [4 byte unsigned] – length limited to

0xFFFF• 65535 bytes

• Status• Language Text

(c) 2015 Independent SAP Technical User Group

Annual Conference, 2015

TDS_LANGUAGE

Here’s the sample “select @@version”

LANGUAGE Token (0x21); variable length. Length [4]: 18 Status [1]: UNUSED (0x00) Text Length [0]: [17] Text [17]: "select @@version"

(c) 2015 Independent SAP Technical User Group

Annual Conference, 2015

Response to TDS_LANGUAGE

Remember the PDU header, and this is a response:

Capture Record Header Source [4]: RESPONSE (0x00000002) Length [4]: 163

PDU Header TDS Packet Type [1]: BUF_RESPONSE (0x04) Status [1]: BUFSTAT_EOM (0x01) Length [2]: 163 Channel [2]: 0 Packet No. [1]: 0 Window [1]: 0

(c) 2015 Independent SAP Technical User Group

Annual Conference, 2015

Response to TDS_LANGUAGE: Row format

This is the TDS_ROWFMT2 token

Describes data type, length, and status of row data

ROWFMT2 Token (0x61); Length [4]: 18 Number of Columns [2]: 1 Column 1 Column Label Length [1]: 0 Catalog Name Length [1]: 0 Schema Length [1]: 0 Table Name Length [1]: 0 Column Name Length [1]: 0 Status [4]: ROW_UPDATABLE + ROW_NULLALLOWED (0x00000030) User Type [4]: 0x00000002 Data Type [1]: VARCHAR Length [1]: 255 Locale Length [1]: 0

(c) 2015 Independent SAP Technical User Group

Annual Conference, 2015

Response to TDS_LANGUAGE: Row format

This is the TDS_ROWFMT2 token

Describes data type, length, and status of row data

ROWFMT2 Token (0x61); Length [4]: 18 Number of Columns [2]: 1 Column 1 Column Label Length [1]: 0 Catalog Name Length [1]: 0 Schema Length [1]: 0 Table Name Length [1]: 0 Column Name Length [1]: 0 Status [4]: ROW_UPDATABLE + ROW_NULLALLOWED (0x00000030) User Type [4]: 0x00000002 Data Type [1]: VARCHAR Length [1]: 255 Locale Length [1]: 0

(c) 2015 Independent SAP Technical User Group

Annual Conference, 2015

Response to TDS_LANGUAGE: Row format

This is the TDS_ROWFMT2 token

Describes data type, length, and status of row data

ROWFMT2 Token (0x61); Length [4]: 18 Number of Columns [2]: 1 Column 1 Column Label Length [1]: 0 Catalog Name Length [1]: 0 Schema Length [1]: 0 Table Name Length [1]: 0 Column Name Length [1]: 0 Status [4]: ROW_UPDATABLE + ROW_NULLALLOWED (0x00000030) User Type [4]: 0x00000002 Data Type [1]: VARCHAR Length [1]: 255 Locale Length [1]: 0

(c) 2015 Independent SAP Technical User Group

Annual Conference, 2015

Response to TDS_LANGUAGE: Row format

This is the TDS_ROWFMT2 token

Describes data type, length, and status of row data

ROWFMT2 Token (0x61); Length [4]: 18 Number of Columns [2]: 1 Column 1 Column Label Length [1]: 0 Catalog Name Length [1]: 0 Schema Length [1]: 0 Table Name Length [1]: 0 Column Name Length [1]: 0 Status [4]: ROW_UPDATABLE + ROW_NULLALLOWED (0x00000030) User Type [4]: 0x00000002 Data Type [1]: VARCHAR Length [1]: 255 Locale Length [1]: 0

(c) 2015 Independent SAP Technical User Group

Annual Conference, 2015

TDS_ROWFMT2 Data Type

The TDS Datatype section describes the fields for the TDS datatype in the format tokens:

(c) 2015 Independent SAP Technical User Group

Annual Conference, 2015

TDS_ROW: The data

The TDS_ROW, 0xD1, token represents a row of data

ROW Token (0xD1); variable length. Column 1 Length [1]: 117 Row data [117]: "Adaptive Server Enterprise/12.5.3/EBF 13331 ESD#7/P/NT (IX86)/OS 4.0/ase1253/1951/32-bit/OPT/Fri Mar 24 02:17:56 2006" (0x41646170746976652053657276657220456E74657270726973652F31322E352E332F4542462031333333312045534423372F502F4E54202849583836292F4F5320342E302F617365313235332F313935312F33322D6269742F4F50542F467269204D61722032342030323A31373A35362032303036)

(c) 2015 Independent SAP Technical User Group

Annual Conference, 2015

TDS_DONE – When things are done

• The TDS_DONE token indicates completion status of the response• One for each statement• On selects it returns rowcount

DONE Token (0xFD); fixed length. Length [0]: [8] Status [2]: DONE_COUNT (0x0010) TranState [2]: TDS_TRAN_PROGRESS (0x0002) Count [4]: 1

(c) 2015 Independent SAP Technical User Group

Annual Conference, 2015

Another select example

This example selects four columns:

create table tds_table (c1 int not null, c2 varchar(20), c3 numeric(10,4), c4 datetime, constraint tds_pk primary key (c1))

(c) 2015 Independent SAP Technical User Group

Annual Conference, 2015

ODBC Connection to select

You can use the login packet to identify the application and the client

Login Record; fixed length. Host Name [30]: "PVEROXP" Host Name Length [1]: 7 User Name [30]: "sa" User Name Length [1]: 2 Password [30]: "sybase" Password Length [1]: 6 Host Process [30]: "5580" Host Process Length [1]: 4

Application Name [30]: "ODBCTEST" Application Name Length [1]: 8 Service Name [30]: "" Service Name Length [1]: 0 Remote Passwords [255]: <universal>/"sybase" Remote Passwords Length [1]: 8 TDS Version [4]: 5.0.0.0 Prog Name [30]: "tdsconn" Prog Name Length [1]: 7 Prog Version [4]: 12.0.5.0 Convert Shorts [1]: 0 4-byte Float Format [1]: 13 4-byte Date Format [1]: 17 Language [30]: "us_english" Language Length [1]: 10

(c) 2015 Independent SAP Technical User Group

Annual Conference, 2015

Getting spid from TDS_DONE response to TDS_LOGIN

• On newer ASE servers [verify the earliest] the TDS_DONE response to Login request contains the spid of the session• Excellent way to match the TDS trace with the ASE

session for trouble-shooting purposes

DONE Token (0xFD); fixed length. Length [0]: [8] Status [2]: DONE_FINAL (0x0000) TranState [2]: TDS_TRAN_PROGRESS (0x0002) Count (unused) [4]: 18

(c) 2015 Independent SAP Technical User Group

Annual Conference, 2015

The TDS_LANGUAGE

The select is executed via the TDS_LANGUAGE eventWhen ODBCTEST calls SQLExecDirect(“SELECT * FROM

tds_table”)

LANGUAGE Token (0x21); variable length. Length [4]: 24 Status [1]: UNUSED (0x00) Text Length [0]: [23] Text [23]: "select * from tds_table"

(c) 2015 Independent SAP Technical User Group

Annual Conference, 2015

ContentsIntroduction to TDS

VersionsPDF documents

TDS DocumentationCapture tools

RiboGuiProxSniffersSrv.log

Tokens and FlowTDS_ENVCHANGE, EED, LANGUAGE, etcSimple select from execution to response, result set

FormatsRow DataParameters

Stored procedure calls with parameters

(c) 2015 Independent SAP Technical User Group

Annual Conference, 2015

Formats

• Row formats are provided for row results and contain description information for the specified column

• TDS tokens TDS_ROWFMT and TDS_ROWFMT2 provide this information.• Used by applications when binding the fields to

program variables• The same concept occurs with parameters

• TDS_PARAMFMT/PARAMFMT2 provide parameter information

(c) 2015 Independent SAP Technical User Group

Annual Conference, 2015

TDS_ROWFMT2 exposedROWFMT2 Token (0x61); Length [4]: 139 Number of Columns [2]: 4 Column 1 Column Label Length [1]: 2 Column Label [2]: "c1" Catalog Name Length [1]: 4 Catalog [4]: "odbc" Schema Length [1]: 3 Scehma [3]: "dbo" Table Name Length [1]: 9 Table Name [9]: "tds_table" Column Name Length [1]: 2 Column Name [2]: "c1" Status [4]: ROW_UPDATABLE (0x00000010) User Type [4]: 0x00000007 Data Type [1]: INT4 Length [0]: [4] Locale Length [1]: 0

(c) 2015 Independent SAP Technical User Group

Annual Conference, 2015

TDS_PARAMFMT exposed

LANGUAGE Token (0x21); variable length. Length [4]: 56

Status [1]: PARAMETERIZED (0x01)

Text Length [0]: [55]

Text [55]: "select * from tds_table where c1=@dr_ta0 and c2=@dr_ta1"

(c) 2015 Independent SAP Technical User Group

Annual Conference, 2015

TDS_PARAMFMT exposedPARAMFMT Token (0xEC); variable length.

Length [2]: 34

Number of Params [2]: 2

Param 1

Name Length [1]: 7

Name [7]: "@dr_ta0"

Status [1]: PARAM_NULLALLOWED (0x20)

User Type [4]: 0

Data Type [1]: INTN

Length [1]: 4

Locale Length [1]: 0

Param 2

Name Length [1]: 7

Name [7]: "@dr_ta1"

Status [1]: PARAM_NULLALLOWED (0x20)

User Type [4]: 0

Data Type [1]: CHAR

Length [1]: 255

Locale Length [1]: 0

(c) 2015 Independent SAP Technical User Group

Annual Conference, 2015

The tds_table row formats

1> select * from tds_table

2> go

c1 c2 c3 c4

----------- -------------------- ------------- -------------------------------

1 TDS_LANGUAGE 2.1000 Mar 8 2015 9:56PM

2 TDS_DBRPC 14.6000 Mar 8 2015 9:56PM

3 TDS_CURDECLARE 8.6100 Mar 8 2015 9:56PM

4 TDS_DYNAMIC 14.7000 Mar 8 2015 9:56PM

5 TDS_ROW 13.1000 Mar 8 2015 9:56PM

(c) 2015 Independent SAP Technical User Group

Annual Conference, 2015

The tds_table row formats

ROWFMT Token (0xEE);

Length [2]: 46

Number of Columns [2]: 4

Column 1

Name Length [1]: 2

Name [2]: "c1"

Status [1]: ROW_UPDATABLE (0x10)

User Type [4]: 7

Data Type [1]: INT4

Length [0]: [4]

Locale Length [1]: 0

(c) 2015 Independent SAP Technical User Group

Annual Conference, 2015

The tds_table row formats

Column 2

Name Length [1]: 2

Name [2]: "c2"

Status [1]: ROW_UPDATABLE (0x10)

User Type [4]: 2

Data Type [1]: VARCHAR

Length [1]: 20

Locale Length [1]: 00

(c) 2015 Independent SAP Technical User Group

Annual Conference, 2015

The tds_table row formats

Column 3

Name Length [1]: 2

Name [2]: "c3"

Status [1]: ROW_UPDATABLE (0x10)

User Type [4]: 10

Data Type [1]: NUMN

Length [1]: 6

Precision [1]: 10

Scale [1]: 4

Locale Length [1]: 0

(c) 2015 Independent SAP Technical User Group

Annual Conference, 2015

The tds_table row formats

Column 4

Name Length [1]: 2

Name [2]: "c4"

Status [1]: ROW_UPDATABLE (0x10)

User Type [4]: 12

Data Type [1]: DATETIM

Length [0]: [8]

Locale Length [1]: 0

(c) 2015 Independent SAP Technical User Group

Annual Conference, 2015

The tds_table row formats: Results

ROW Token (0xD1); variable length.

Column 1

Length [0]: [4]

Row data [4]: 1 (0x00000001)

Column 2

Length [1]: 12

Row data [12]: "TDS_LANGUAGE" (0x5444535F4C414E4755414745)

Column 3

Length [1]: 6

Row data [6]: 2.1000

Column 4

Length [0]: [8]

Row data [8]: 2015-03-08 21:56:51.533

(c) 2015 Independent SAP Technical User Group

Annual Conference, 2015

ContentsIntroduction to TDS

VersionsPDF documents

TDS DocumentationCapture tools

RiboGuiProxSniffersSrv.log

Tokens and FlowTDS_ENVCHANGE, EED, LANGUAGE, etcSimple select from execution to response, result set

FormatsRow DataParameters

Stored procedure calls with parameters

(c) 2015 Independent SAP Technical User Group

Annual Conference, 2015

The sp_tds_proc procedure

create procedure sp_tds_proc (

@p1 int,

@p2 varchar(50),

@p3 varchar(50) output

)

as

select c3, c4 from tds_table where c1= @p1 and c2 = @p2

select @p3 = ‘Sent from sp_tds_proc’

return 0

go

(c) 2015 Independent SAP Technical User Group

Annual Conference, 2015

The sp_tds_proc procedure

- Cover four concepts of stored procedures- Input/Output parameters- Return status- Formats (similar to Row Results)- Result set processing

(c) 2015 Independent SAP Technical User Group

Annual Conference, 2015

The sp_tds_proc procedure

Parameter: 3 Value: nullParameter buffer size: 4 chars Enter data type :char Enter parameter name with '@':@p3input or output parameter?:outputtarget_format.status : 1024Check for null

ct_results : retcode : SUCCEEDTYPE: ROW_RESULT----------Row 1----------c3 : 2.1000c4 : Mar 8 2015 9:56PM ct_results : retcode : SUCCEEDTYPE: CMD_DONE(1 rows affected)ct_results : retcode : SUCCEEDTYPE: STATUS_RESULT----------Row 1----------Return Status : 0 ct_results : retcode : SUCCEEDTYPE: PARAM_RESULT----------Row 1----------@p3 : Sent from sp_tds_proc ct_results : retcode : SUCCEEDTYPE: CMD_DONE(1 rows affected)ct_results : retcode : END_RESULTS

Run it through sqltest

Enter the values:1> sp_tds_proc 1,'TDS_LANGUAGE',null

Parameter: 1 Value: 1Parameter buffer size: 1 charsEnter data:intEnter parameter name with '@':@p1input or output parameter?:inputtarget_format.status : 256current_token is 1current_token length is 1Parameter: 2 Value: 'TDS_LANGUAGE'Parameter buffer size: 14 charsEnter data type :charEnter parameter name with '@':@p2input or output parameter?:inputtarget_format.status : 256Check for null

(c) 2015 Independent SAP Technical User Group

Annual Conference, 2015

Parameters

Param 2

Name Length [1]: 3

Name [3]: "@p2"

Status [1]: <unrecognized> (0x00)

User Type [4]: 0

Data Type [1]: LONGCHAR

Length [4]: 32676

Locale Length [1]: 0

Param 3

Name Length [1]: 3

Name [3]: "@p3"

Status [1]: PARAM_RETURN (0x01)

User Type [4]: 0

Data Type [1]: LONGCHAR

Length [4]: 32676

Locale Length [1]: 0

PARAMS Token (0xD7); variable length.

Param 1

Length [1]: 4

Param data [4]: 1 (0x00000001)

Param 2

Length [4]: 12

Param data [12]: "TDS_LANGUAGE"

Param 3

Length [4]: 0

Param data [0]: [null]

- Procedure takes input parameters to pass values to ASE

- Output parameters return information from ASE

PARAMFMT2 Token (0x20); variable length.

Length [4]: 53

Number of Params [2]: 3

Param 1

Name Length [1]: 3

Name [3]: "@p1"

Status [1]: <unrecognized>

(0x00)

User Type [4]: 0

Data Type [1]: INTN

Length [1]: 4

Locale Length [1]: 0

(c) 2015 Independent SAP Technical User Group

Annual Conference, 2015

Response

ROWFMT Token (0xEE); Length [2]: 25 Number of Columns [2]: 2 Column 1 Name Length [1]: 2 Name [2]: "c3" Status [1]: ROW_UPDATABLE (0x10) User Type [4]: 10 Data Type [1]: NUMN Length [1]: 6 Precision [1]: 10 Scale [1]: 4 Locale Length [1]: 0 Column 2 Name Length [1]: 2 Name [2]: "c4" Status [1]: ROW_UPDATABLE (0x10) User Type [4]: 12 Data Type [1]: DATETIM Length [0]: [8] Locale Length [1]: 0 ROW Token (0xD1); variable length. Column 1 Length [1]: 6 Row data [6]: 2.1000 Column 2 Length [0]: [8] Row data [8]: 2015-03-08 21:56:51.533

- Row Results-Format

-Data

- DONEINPROC tokens-One each for Row results, 1 row affected

-Return Status-Counts as another row affected

-Output parameter -Handled as row result mechanical

- Counts as another row affected

- RETURN Status-TDS_RETURNSTATUS

-Returns status information to client

-Can be used to flag various types of errors

- Output parameter-PARAMFMT

-PARAMS (Data returned, treated like row result)

(c) 2015 Independent SAP Technical User Group

Annual Conference, 2015

Response

RETURNSTATUS Token (0x79); fixed length. Length [0]: [4] Status [4]: 0x00000000 PARAMFMT Token (0xEC); variable length. Length [2]: 17 Number of Params [2]: 1 Param 1 Name Length [1]: 3 Name [3]: "@p3" Status [1]: PARAM_RETURN (0x01) User Type [4]: 2 Data Type [1]: LONGCHAR Length [4]: 16384 Locale Length [1]: 0 PARAMS Token (0xD7); variable length. Param 1 Length [4]: 21 Param data [21]: "Sent from sp_tds_proc" DONE Token (0xFD); fixed length. Length [0]: [8] Status [2]: DONE_FINAL (0x0000) TranState [2]: TDS_TRAN_PROGRESS (0x0002) Count (unused) [4]: 1

DONEINPROC Token (0xFF); fixed length. Length [0]: [8] Status [2]: DONE_MORE + DONE_COUNT + DONE_EVENT (0x0051) TranState [2]: TDS_TRAN_PROGRESS (0x0002) Count [4]: 1 DONEINPROC Token (0xFF); fixed length. Length [0]: [8] Status [2]: DONE_MORE + DONE_COUNT + DONE_EVENT (0x0051) TranState [2]: TDS_TRAN_PROGRESS (0x0002) Count [4]: 1 DONEINPROC Token (0xFF); fixed length. Length [0]: [8] Status [2]: DONE_MORE + DONE_COUNT + DONE_EVENT (0x0051) TranState [2]: TDS_TRAN_PROGRESS (0x0002) Count [4]: 1

(c) 2015 Independent SAP Technical User Group

Annual Conference, 2015

RETURNSTATUSUsed to provide status from the procedure.

Application code can test this value to determine various events

ASE provides some negative values for various errors

Coder can test values – so like”8” might mean we just called 8 triggers to update various tables.

(c) 2015 Independent SAP Technical User Group

Annual Conference, 2015

Summary

TDS used to troubleshoot errorsOn client or ASE?

Reverse EngineerCan use the output to write test code to represent

problemUnderstand communication between Server and Client

(c) 2015 Independent SAP Technical User Group

Annual Conference, 2015

Question and Answer

Questions

(c) 2015 Independent SAP Technical User Group

Annual Conference, 2015

ISUG articles

• TDS Revealed: A Primer to Understanding the Communication Language of ASE• Issue 2, 2009

• Chomping on the Network with Wireshark• November 2010 and January 2011

• TDS Case Studies: Root Cause Analysis Techniques for ASE Drivers• September 2010

(c) 2015 Independent SAP Technical User Group

Annual Conference, 2015

More Resources• Product Documentation

• ht tp://help.sap.com /adapt ive-server-enterprise?current= database&show_children= false

• How to get best results from an SAP Search

• ht tps://service.sap.com/sap/support /notes/2081285

• Service Market Place/Support

• ht tps://service.sap.com

• ht tps://support .sap.com/hom e.htm l

• SAP Com munit ies

• ht tp://scn.sap.com /com m unity/sybase-adapt ive-server-enterprise

• ht tp://scn.sap.com /com m unity/developer-center/oltp-db

• Social Media Product Support Channels

• ht tps://www.facebook.com /SapProductSupport

• ht tps://twit ter.com /SAPSupporthelp