mssql 12.3.0 → 12.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +92 -15
- package/lib/tedious/request.js +55 -25
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
**Microsoft SQL Server client for Node.js**
|
|
4
4
|
|
|
5
|
-
[![NPM Version][npm-image]][npm-url] [![NPM Downloads][downloads-image]][downloads-url]
|
|
5
|
+
[![NPM Version][npm-image]][npm-url] [![NPM Downloads][downloads-image]][downloads-url]
|
|
6
6
|
|
|
7
7
|
Supported TDS drivers:
|
|
8
8
|
|
|
@@ -137,6 +137,8 @@ const config = {
|
|
|
137
137
|
* [ConnectionPool](#connections-1)
|
|
138
138
|
* [connect](#connect-callback)
|
|
139
139
|
* [close](#close)
|
|
140
|
+
* [Pool properties](#pool-properties)
|
|
141
|
+
* [parseConnectionString](#connectionpoolparseconnectionstring-connectionstring)
|
|
140
142
|
|
|
141
143
|
### Requests
|
|
142
144
|
|
|
@@ -144,6 +146,8 @@ const config = {
|
|
|
144
146
|
* [execute](#execute-procedure-callback)
|
|
145
147
|
* [input](#input-name-type-value)
|
|
146
148
|
* [output](#output-name-type-value)
|
|
149
|
+
* [replaceInput](#replaceinput-name-type-value-1)
|
|
150
|
+
* [replaceOutput](#replaceoutput-name-type-value)
|
|
147
151
|
* [toReadableStream](#toReadableStream)
|
|
148
152
|
* [pipe](#pipe-stream)
|
|
149
153
|
* [query](#query-command-callback)
|
|
@@ -181,8 +185,10 @@ const config = {
|
|
|
181
185
|
* [Metadata](#metadata)
|
|
182
186
|
* [Data Types](#data-types)
|
|
183
187
|
* [SQL injection](#sql-injection)
|
|
184
|
-
* [Known Issues](#known-issues)
|
|
185
188
|
* [Contributing](https://github.com/tediousjs/node-mssql/wiki/Contributing)
|
|
189
|
+
* [11.x to 12.x changes](#11x-to-12x-changes)
|
|
190
|
+
* [10.x to 11.x changes](#10x-to-11x-changes)
|
|
191
|
+
* [9.x to 10.x changes](#9x-to-10x-changes)
|
|
186
192
|
* [8.x to 9.x changes](#8x-to-9x-changes)
|
|
187
193
|
* [7.x to 8.x changes](#7x-to-8x-changes)
|
|
188
194
|
* [6.x to 7.x changes](#6x-to-7x-changes)
|
|
@@ -724,7 +730,7 @@ ___
|
|
|
724
730
|
|
|
725
731
|
### MSNodeSQLv8
|
|
726
732
|
|
|
727
|
-
Alternative driver
|
|
733
|
+
Alternative driver for Windows (32 or 64-bit) or Linux/macOS (64-bit only). It's not part of the default package so it must be [installed](#msnodesqlv8-driver) in addition. Supports [Windows/Trusted Connection authentication](#windows-authentication-example-using-msnodesqlv8).
|
|
728
734
|
|
|
729
735
|
**To use this driver you must use this `require` statement:**
|
|
730
736
|
|
|
@@ -816,6 +822,36 @@ __Example__
|
|
|
816
822
|
pool.close()
|
|
817
823
|
```
|
|
818
824
|
|
|
825
|
+
---------------------------------------
|
|
826
|
+
|
|
827
|
+
### Pool properties
|
|
828
|
+
|
|
829
|
+
These properties are available on a connected `ConnectionPool` instance (after `connect()` has resolved):
|
|
830
|
+
|
|
831
|
+
- **pool.healthy** - `Boolean` - Whether the pool is able to create new connections.
|
|
832
|
+
- **pool.size** - `Number` - Total number of connections in the pool (free + used + pending creation).
|
|
833
|
+
- **pool.available** - `Number` - Number of free connections in the pool.
|
|
834
|
+
- **pool.pending** - `Number` - Number of pending connection acquisition requests.
|
|
835
|
+
- **pool.borrowed** - `Number` - Number of connections currently in use.
|
|
836
|
+
- **pool.connected** - `Boolean` - Whether the pool is connected.
|
|
837
|
+
- **pool.connecting** - `Boolean` - Whether the pool is currently connecting.
|
|
838
|
+
|
|
839
|
+
---------------------------------------
|
|
840
|
+
|
|
841
|
+
### ConnectionPool.parseConnectionString (connectionString)
|
|
842
|
+
|
|
843
|
+
Parses a connection string into a configuration object. This is a static method.
|
|
844
|
+
|
|
845
|
+
__Arguments__
|
|
846
|
+
|
|
847
|
+
- **connectionString** - Classic or Azure AD connection string.
|
|
848
|
+
|
|
849
|
+
__Example__
|
|
850
|
+
|
|
851
|
+
```javascript
|
|
852
|
+
const config = sql.ConnectionPool.parseConnectionString('Server=localhost,1433;Database=mydb;User Id=sa;Password=pwd')
|
|
853
|
+
```
|
|
854
|
+
|
|
819
855
|
## Request
|
|
820
856
|
|
|
821
857
|
```javascript
|
|
@@ -903,6 +939,13 @@ __JS Data Type To SQL Data Type Map__
|
|
|
903
939
|
|
|
904
940
|
Default data type for unknown object is `sql.NVarChar`.
|
|
905
941
|
|
|
942
|
+
When a `Number` value is provided without an explicit type, the library inspects the value to choose the best SQL type:
|
|
943
|
+
- Integers within the 32-bit signed range → `sql.Int`
|
|
944
|
+
- Integers outside the 32-bit range → `sql.BigInt`
|
|
945
|
+
- Non-integer numbers → `sql.Float`
|
|
946
|
+
|
|
947
|
+
JavaScript `bigint` primitives follow the same range logic (`sql.Int` for values within the 32-bit signed range, `sql.BigInt` otherwise).
|
|
948
|
+
|
|
906
949
|
You can define your own type map.
|
|
907
950
|
|
|
908
951
|
```javascript
|
|
@@ -946,6 +989,46 @@ __Errors__ (synchronous)
|
|
|
946
989
|
|
|
947
990
|
---------------------------------------
|
|
948
991
|
|
|
992
|
+
### replaceInput (name, type, value)
|
|
993
|
+
|
|
994
|
+
Replace an existing input parameter on the request. If the parameter was previously added with `input()`, it is removed and re-added with the new type and value. Useful when building queries dynamically or re-using a `Request` object.
|
|
995
|
+
|
|
996
|
+
__Arguments__
|
|
997
|
+
|
|
998
|
+
- **name** - Name of the input parameter without @ char.
|
|
999
|
+
- **type** - SQL data type of input parameter.
|
|
1000
|
+
- **value** - Input parameter value.
|
|
1001
|
+
|
|
1002
|
+
Unlike `input()`, `replaceInput()` requires an explicit SQL type — auto type inference is not supported.
|
|
1003
|
+
|
|
1004
|
+
__Example__
|
|
1005
|
+
|
|
1006
|
+
```javascript
|
|
1007
|
+
request.input('myval', sql.Int, 1)
|
|
1008
|
+
request.replaceInput('myval', sql.Int, 2)
|
|
1009
|
+
```
|
|
1010
|
+
|
|
1011
|
+
---------------------------------------
|
|
1012
|
+
|
|
1013
|
+
### replaceOutput (name, type, [value])
|
|
1014
|
+
|
|
1015
|
+
Replace an existing output parameter on the request.
|
|
1016
|
+
|
|
1017
|
+
__Arguments__
|
|
1018
|
+
|
|
1019
|
+
- **name** - Name of the output parameter without @ char.
|
|
1020
|
+
- **type** - SQL data type of output parameter.
|
|
1021
|
+
- **value** - Output parameter value initial value. Optional.
|
|
1022
|
+
|
|
1023
|
+
__Example__
|
|
1024
|
+
|
|
1025
|
+
```javascript
|
|
1026
|
+
request.output('myval', sql.Int)
|
|
1027
|
+
request.replaceOutput('myval', sql.BigInt)
|
|
1028
|
+
```
|
|
1029
|
+
|
|
1030
|
+
---------------------------------------
|
|
1031
|
+
|
|
949
1032
|
### toReadableStream
|
|
950
1033
|
|
|
951
1034
|
Convert request to a Node.js ReadableStream
|
|
@@ -1044,7 +1127,7 @@ request.query('select 1 as number; select 2 as number', (err, result) => {
|
|
|
1044
1127
|
|
|
1045
1128
|
### batch (batch, [callback])
|
|
1046
1129
|
|
|
1047
|
-
Execute the SQL command. Unlike [query](#query-command-callback), it doesn't use `sp_executesql`, so is not likely that SQL Server will reuse the execution plan it generates for the SQL. Use this only in special cases, for example when you need to execute commands like `create procedure` which can't be executed with [query](#query-command-callback)
|
|
1130
|
+
Execute the SQL command. Unlike [query](#query-command-callback), it doesn't use `sp_executesql`, so is not likely that SQL Server will reuse the execution plan it generates for the SQL. Use this only in special cases, for example when you need to execute commands like `create procedure` which can't be executed with [query](#query-command-callback). Also you should use this if you plan to work with local temporary tables ([more information here](http://weblogs.sqlteam.com/mladenp/archive/2006/11/03/17197.aspx)).
|
|
1048
1131
|
|
|
1049
1132
|
NOTE: Table-Valued Parameter (TVP) is not supported in batch.
|
|
1050
1133
|
|
|
@@ -1072,8 +1155,6 @@ __Errors__
|
|
|
1072
1155
|
- ENOTBEGUN (`TransactionError`) - Transaction has not begun.
|
|
1073
1156
|
- EABORT (`TransactionError`) - Transaction was aborted (by user or because of an error).
|
|
1074
1157
|
|
|
1075
|
-
You can enable multiple recordsets in queries with the `request.multiple = true` command.
|
|
1076
|
-
|
|
1077
1158
|
---------------------------------------
|
|
1078
1159
|
|
|
1079
1160
|
### bulk (table, [options,] [callback])
|
|
@@ -2139,12 +2220,12 @@ request.query('select @myval as myval', (err, result) => {
|
|
|
2139
2220
|
})
|
|
2140
2221
|
```
|
|
2141
2222
|
|
|
2142
|
-
##
|
|
2143
|
-
|
|
2144
|
-
### Tedious
|
|
2223
|
+
## 11.x to 12.x changes
|
|
2145
2224
|
|
|
2146
|
-
-
|
|
2147
|
-
-
|
|
2225
|
+
- Config objects are no longer cloned by the library. Mutating a config object after passing it to a `ConnectionPool` results in undefined behaviour.
|
|
2226
|
+
- Removed `rfdc` dependency
|
|
2227
|
+
- Upgraded to tedious version 19
|
|
2228
|
+
- Upgraded `@tediousjs/connection-string` to 0.6.x
|
|
2148
2229
|
|
|
2149
2230
|
## 10.x to 11.x changes
|
|
2150
2231
|
|
|
@@ -2220,10 +2301,6 @@ to create new connections or not
|
|
|
2220
2301
|
[npm-url]: https://www.npmjs.com/package/mssql
|
|
2221
2302
|
[downloads-image]: https://img.shields.io/npm/dm/mssql.svg?style=flat-square
|
|
2222
2303
|
[downloads-url]: https://www.npmjs.com/package/mssql
|
|
2223
|
-
[david-image]: https://img.shields.io/david/tediousjs/node-mssql.svg?style=flat-square
|
|
2224
|
-
[david-url]: https://david-dm.org/tediousjs/node-mssql
|
|
2225
|
-
[appveyor-image]: https://ci.appveyor.com/api/projects/status/e5gq1a0ujwams9t7/branch/master?svg=true
|
|
2226
|
-
[appveyor-url]: https://ci.appveyor.com/project/tediousjs/node-mssql
|
|
2227
2304
|
|
|
2228
2305
|
[tedious-url]: https://www.npmjs.com/package/tedious
|
|
2229
2306
|
[msnodesqlv8-url]: https://www.npmjs.com/package/msnodesqlv8
|
package/lib/tedious/request.js
CHANGED
|
@@ -200,9 +200,13 @@ const parameterCorrection = function (value) {
|
|
|
200
200
|
}
|
|
201
201
|
|
|
202
202
|
for (const col of value.columns) {
|
|
203
|
+
const tediousType = getTediousType(col.type)
|
|
204
|
+
if (tediousType === tds.TYPES.Variant) {
|
|
205
|
+
throw new RequestError(`Column '${col.name}' in TVP '${value.schema ? value.schema + '.' : ''}${value.name}' uses sql_variant which is not supported by the tedious driver for TVP column types. Consider using a more specific data type.`, 'EARGS')
|
|
206
|
+
}
|
|
203
207
|
tvp.columns.push({
|
|
204
208
|
name: col.name,
|
|
205
|
-
type:
|
|
209
|
+
type: tediousType,
|
|
206
210
|
length: col.length,
|
|
207
211
|
scale: col.scale,
|
|
208
212
|
precision: col.precision
|
|
@@ -664,9 +668,18 @@ class Request extends BaseRequest {
|
|
|
664
668
|
} catch (e) {
|
|
665
669
|
e.message = `Validation failed for parameter '${name}'. ${e.message}`
|
|
666
670
|
const err = new RequestError(e, 'EPARAM')
|
|
671
|
+
delete this._cancel
|
|
672
|
+
|
|
673
|
+
if (!hasReturned) {
|
|
674
|
+
for (const event in errorHandlers) {
|
|
675
|
+
connection.removeListener(event, errorHandlers[event])
|
|
676
|
+
}
|
|
667
677
|
|
|
668
|
-
|
|
669
|
-
|
|
678
|
+
this.parent.release(connection)
|
|
679
|
+
hasReturned = true
|
|
680
|
+
return callback(err)
|
|
681
|
+
}
|
|
682
|
+
return
|
|
670
683
|
}
|
|
671
684
|
}
|
|
672
685
|
|
|
@@ -703,21 +716,23 @@ class Request extends BaseRequest {
|
|
|
703
716
|
|
|
704
717
|
req.sqlTextOrProcedure = `declare ${declarations.join(', ')};select ${assigns.join(', ')};${req.sqlTextOrProcedure};${batchHasOutput ? (`select 1 as [___return___], ${selects.join(', ')}`) : ''}`
|
|
705
718
|
}
|
|
706
|
-
} else {
|
|
707
|
-
for (const name in this.parameters) {
|
|
708
|
-
if (!objectHasProperty(this.parameters, name)) {
|
|
709
|
-
continue
|
|
710
|
-
}
|
|
711
|
-
const param = this.parameters[name]
|
|
712
|
-
if (param.io === 1) {
|
|
713
|
-
req.addParameter(param.name, getTediousType(param.type), parameterCorrection(param.value), { length: param.length, scale: param.scale, precision: param.precision })
|
|
714
|
-
} else {
|
|
715
|
-
req.addOutputParameter(param.name, getTediousType(param.type), parameterCorrection(param.value), { length: param.length, scale: param.scale, precision: param.precision })
|
|
716
|
-
}
|
|
717
|
-
}
|
|
718
719
|
}
|
|
719
720
|
|
|
720
721
|
try {
|
|
722
|
+
if (!this._isBatch) {
|
|
723
|
+
for (const name in this.parameters) {
|
|
724
|
+
if (!objectHasProperty(this.parameters, name)) {
|
|
725
|
+
continue
|
|
726
|
+
}
|
|
727
|
+
const param = this.parameters[name]
|
|
728
|
+
if (param.io === 1) {
|
|
729
|
+
req.addParameter(param.name, getTediousType(param.type), parameterCorrection(param.value), { length: param.length, scale: param.scale, precision: param.precision })
|
|
730
|
+
} else {
|
|
731
|
+
req.addOutputParameter(param.name, getTediousType(param.type), parameterCorrection(param.value), { length: param.length, scale: param.scale, precision: param.precision })
|
|
732
|
+
}
|
|
733
|
+
}
|
|
734
|
+
}
|
|
735
|
+
|
|
721
736
|
connection[this._isBatch ? 'execSqlBatch' : 'execSql'](req)
|
|
722
737
|
} catch (error) {
|
|
723
738
|
handleError(true, connection, error)
|
|
@@ -983,19 +998,34 @@ class Request extends BaseRequest {
|
|
|
983
998
|
output[parameterName] = value
|
|
984
999
|
})
|
|
985
1000
|
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
|
|
1001
|
+
try {
|
|
1002
|
+
for (const name in this.parameters) {
|
|
1003
|
+
if (!objectHasProperty(this.parameters, name)) {
|
|
1004
|
+
continue
|
|
1005
|
+
}
|
|
1006
|
+
const param = this.parameters[name]
|
|
1007
|
+
if (param.io === 1) {
|
|
1008
|
+
req.addParameter(param.name, getTediousType(param.type), parameterCorrection(param.value), { length: param.length, scale: param.scale, precision: param.precision })
|
|
1009
|
+
} else {
|
|
1010
|
+
req.addOutputParameter(param.name, getTediousType(param.type), parameterCorrection(param.value), { length: param.length, scale: param.scale, precision: param.precision })
|
|
1011
|
+
}
|
|
989
1012
|
}
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
|
|
1013
|
+
|
|
1014
|
+
connection.callProcedure(req)
|
|
1015
|
+
} catch (error) {
|
|
1016
|
+
const err = error instanceof RequestError ? error : new RequestError(error, 'EREQUEST')
|
|
1017
|
+
delete this._cancel
|
|
1018
|
+
|
|
1019
|
+
if (!hasReturned) {
|
|
1020
|
+
for (const event in errorHandlers) {
|
|
1021
|
+
connection.removeListener(event, errorHandlers[event])
|
|
1022
|
+
}
|
|
1023
|
+
|
|
1024
|
+
this.parent.release(connection)
|
|
1025
|
+
hasReturned = true
|
|
1026
|
+
callback(err)
|
|
995
1027
|
}
|
|
996
1028
|
}
|
|
997
|
-
|
|
998
|
-
connection.callProcedure(req)
|
|
999
1029
|
})
|
|
1000
1030
|
})
|
|
1001
1031
|
}
|