📄 tdscore.java
字号:
* Obtain the counts from a batch of SQL updates. * <p/> * If an error occurs Sybase will continue processing a batch consisting of * TDS_LANGUAGE records whilst SQL Server will stop after the first error. * Sybase will also stop after the first error when executing RPC calls. * For Sybase only therefore, this method returns the JDBC3 * <code>EXECUTE_FAILED</code> constant in the counts array when a * statement fails with an error. For Sybase, care is taken to ensure that * <code>SQLException</code>s are chained because there could be several * errors reported in a batch. * * @param counts the <code>ArrayList</code> containing the update counts * @param sqlEx any previous <code>SQLException</code>(s) encountered * @return updated <code>SQLException</code> or <code>null</code> if no * error has yet occured */ SQLException getBatchCounts(ArrayList counts, SQLException sqlEx) { Integer lastCount = JtdsStatement.SUCCESS_NO_INFO; try { checkOpen(); while (!endOfResponse) { nextToken(); if (currentToken.isResultSet()) { // Serious error, statement must not return a result set throw new SQLException( Messages.get("error.statement.batchnocount"), "07000"); } // // Analyse type of end token and try to extract correct // update count when calling stored procs. // switch (currentToken.token) { case TDS_DONE_TOKEN: if ((currentToken.status & DONE_ERROR) != 0 || lastCount == JtdsStatement.EXECUTE_FAILED) { if (connection.getServerType() == Driver.SYBASE) { // Sybase can continue batch so flag this count counts.add(JtdsStatement.EXECUTE_FAILED); } } else { if (currentToken.isUpdateCount()) { counts.add(new Integer(currentToken.updateCount)); } else { counts.add(lastCount); } } lastCount = JtdsStatement.SUCCESS_NO_INFO; break; case TDS_DONEINPROC_TOKEN: if ((currentToken.status & DONE_ERROR) != 0) { lastCount = JtdsStatement.EXECUTE_FAILED; } else if (currentToken.isUpdateCount()) { lastCount = new Integer(currentToken.updateCount); } break; case TDS_DONEPROC_TOKEN: if ((currentToken.status & DONE_ERROR) != 0 || lastCount == JtdsStatement.EXECUTE_FAILED) { if (connection.getServerType() == Driver.SYBASE) { // Sybase can continue batch so flag this count counts.add(JtdsStatement.EXECUTE_FAILED); } } else { counts.add(lastCount); } lastCount = JtdsStatement.SUCCESS_NO_INFO; break; } } // // Check for any exceptions // messages.checkErrors(); } catch (SQLException e) { // // Chain all exceptions // if (sqlEx != null) { sqlEx.setNextException(e); } else { sqlEx = e; } } finally { while (!endOfResponse) { // Flush rest of response try { nextToken(); } catch (SQLException ex) { // Chain any exceptions to the BatchUpdateException if (sqlEx != null) { sqlEx.setNextException(ex); } else { sqlEx = ex; } } } } return sqlEx; }// ---------------------- Private Methods from here --------------------- /** * Write a TDS login packet string. Text followed by padding followed * by a byte sized length. */ private void putLoginString(String txt, int len) throws IOException { byte[] tmp = Support.encodeString(connection.getCharset(), txt); out.write(tmp, 0, len); out.write((byte) (tmp.length < len ? tmp.length : len)); } /** * Send the SQL Server 2000 pre login packet. * <p>Packet contains; netlib version, ssl mode, instance * and process ID. * @param instance * @param forceEncryption * @throws IOException */ private void sendPreLoginPacket(String instance, boolean forceEncryption) throws IOException { out.setPacketType(PRELOGIN_PKT); // Write Netlib pointer out.write((short)0); out.write((short)21); out.write((byte)6); // Write Encrypt flag pointer out.write((short)1); out.write((short)27); out.write((byte)1); // Write Instance name pointer out.write((short)2); out.write((short)28); out.write((byte)(instance.length()+1)); // Write process ID pointer out.write((short)3); out.write((short)(28+instance.length()+1)); out.write((byte)4); // Write terminator out.write((byte)0xFF); // Write fake net lib ID 8.341.0 out.write(new byte[]{0x08, 0x00, 0x01, 0x55, 0x00, 0x00}); // Write force encryption flag out.write((byte)(forceEncryption? 1: 0)); // Write instance name out.writeAscii(instance); out.write((byte)0); // Write dummy process ID out.write(new byte[]{0x01, 0x02, 0x00, 0x00}); // out.flush(); } /** * Process the pre login acknowledgement from the server. * <p>Packet contains; server version no, SSL mode, instance name * and process id. * <p>Server returns the following values for SSL mode: * <ol> * <ll>0 = Certificate installed encrypt login packet only. * <li>1 = Certificate installed client requests force encryption. * <li>2 = No certificate no encryption possible. * <li>3 = Server requests force encryption. * </ol> * @return The server side SSL mode. * @throws IOException */ private int readPreLoginPacket() throws IOException { byte list[][] = new byte[8][]; byte data[][] = new byte[8][]; int recordCount = 0; byte record[] = new byte[5]; // Read entry pointers record[0] = (byte)in.read(); while ((record[0] & 0xFF) != 0xFF) { if (recordCount == list.length) { throw new IOException("Pre Login packet has more than 8 entries"); } // Read record in.read(record, 1, 4); list[recordCount++] = record; record = new byte[5]; record[0] = (byte)in.read(); } // Read entry data for (int i = 0; i < recordCount; i++) { byte value[] = new byte[(byte)list[i][4]]; in.read(value); data[i] = value; } if (Logger.isActive()) { // Diagnostic dump Logger.println("PreLogin server response"); for (int i = 0; i < recordCount; i++) { Logger.println("Record " + i+ " = " + Support.toHex(data[i])); } } if (recordCount > 1) { return data[1][0]; // This is the server side SSL mode } else { // Response too short to include SSL mode! return SSL_NO_ENCRYPT; } } /** * TDS 4.2 Login Packet. * * @param serverName server host name * @param user user name * @param password user password * @param charset required server character set * @param appName application name * @param progName program name * @param wsid workstation ID * @param language server language for messages * @param packetSize required network packet size * @throws IOException if an I/O error occurs */ private void send42LoginPkt(final String serverName, final String user, final String password, final String charset, final String appName, final String progName, final String wsid, final String language, final int packetSize) throws IOException { final byte[] empty = new byte[0]; out.setPacketType(LOGIN_PKT); putLoginString(wsid, 30); // Host name putLoginString(user, 30); // user name putLoginString(password, 30); // password putLoginString("00000123", 30); // hostproc (offset 93 0x5d) out.write((byte) 3); // type of int2 out.write((byte) 1); // type of int4 out.write((byte) 6); // type of char out.write((byte) 10);// type of flt out.write((byte) 9); // type of date out.write((byte) 1); // notify of use db out.write((byte) 1); // disallow dump/load and bulk insert out.write((byte) 0); // sql interface type out.write((byte) 0); // type of network connection out.write(empty, 0, 7); putLoginString(appName, 30); // appname putLoginString(serverName, 30); // server name out.write((byte)0); // remote passwords out.write((byte)password.length()); byte[] tmp = Support.encodeString(connection.getCharset(), password); out.write(tmp, 0, 253); out.write((byte) (tmp.length + 2)); out.write((byte) 4); // tds version out.write((byte) 2); out.write((byte) 0); out.write((byte) 0); putLoginString(progName, 10); // prog name out.write((byte) 6); // prog version out.write((byte) 0); out.write((byte) 0); out.write((byte) 0); out.write((byte) 0); // auto convert short out.write((byte) 0x0D); // type of flt4 out.write((byte) 0x11); // type of date4 putLoginString(language, 30); // language out.write((byte) 1); // notify on lang change out.write((short) 0); // security label hierachy out.write((byte) 0); // security encrypted out.write(empty, 0, 8); // security components out.write((short) 0); // security spare putLoginString(charset, 30); // Character set out.write((byte) 1); // notify on charset change putLoginString(String.valueOf(packetSize), 6); // length of tds packets out.write(empty, 0, 8); // pad out to a longword out.flush(); // Send the packet endOfResponse = false; } /** * TDS 5.0 Login Packet. * <P> * @param serverName server host name * @param user user name * @param password user password * @param charset required server character set * @param appName application name * @param progName library name * @param wsid workstation ID * @param language server language for messages * @param packetSize required network packet size * @throws IOException if an I/O error occurs */ private void send50LoginPkt(final String serverName, final String user, final String password, final String charset, final String appName, final String progName, final String wsid, final String language, final int packetSize) throws IOException { final byte[] empty = new byte[0]; out.setPacketType(LOGIN_PKT); putLoginString(wsid, 30); // Host name putLoginString(user, 30); // user name putLoginString(password, 30); // password putLoginString("00000123", 30); // hostproc (offset 93 0x5d) out.write((byte) 3); // type of int2 out.write((byte) 1); // type of int4 out.write((byte) 6); // type of char out.write((byte) 10);// type of flt out.write((byte) 9); // type of date out.write((byte) 1); // notify of use db out.write((byte) 1); // disallow dump/load and bulk insert out.write((byte) 0); // sql interface type out.write((byte) 0); // type of network connection out.write(empty, 0, 7); putLoginString(appName, 30); // appname putLoginString(serverName, 30); // server name out.write((byte)0); // remote passwords o
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -