mirror of
https://github.com/typeorm/typeorm.git
synced 2025-12-08 21:26:23 +00:00
fix: bulk insert NULL values in Oracle (#11363)
resolve issue with bulk insert of NULL values for non VARCHAR2 types in Oracle.
This commit is contained in:
parent
a29e04750d
commit
bcaa0bf071
@ -874,7 +874,8 @@ export class InsertQueryBuilder<
|
||||
}
|
||||
} else if (
|
||||
value === null &&
|
||||
this.connection.driver.options.type === "spanner"
|
||||
(this.connection.driver.options.type === "spanner" ||
|
||||
this.connection.driver.options.type === "oracle")
|
||||
) {
|
||||
expression += "NULL"
|
||||
|
||||
|
||||
@ -9,4 +9,7 @@ export class User {
|
||||
|
||||
@Column()
|
||||
name: string
|
||||
|
||||
@Column({ nullable: true })
|
||||
memberId: number
|
||||
}
|
||||
|
||||
@ -57,9 +57,9 @@ describe("query builder > insert", () => {
|
||||
},
|
||||
})
|
||||
users.should.be.eql([
|
||||
{ id: 1, name: "Alex Messer" },
|
||||
{ id: 2, name: "Dima Zotov" },
|
||||
{ id: 3, name: "Muhammad Mirzoev" },
|
||||
{ id: 1, name: "Alex Messer", memberId: null },
|
||||
{ id: 2, name: "Dima Zotov", memberId: null },
|
||||
{ id: 3, name: "Muhammad Mirzoev", memberId: null },
|
||||
])
|
||||
}),
|
||||
))
|
||||
@ -67,22 +67,29 @@ describe("query builder > insert", () => {
|
||||
it("should perform bulk insertion correctly", () =>
|
||||
Promise.all(
|
||||
connections.map(async (connection) => {
|
||||
// it is skipped for Oracle and SAP because it does not support bulk insertion
|
||||
if (
|
||||
connection.driver.options.type === "oracle" ||
|
||||
connection.driver.options.type === "sap"
|
||||
)
|
||||
// it is skipped for SAP because it does not support bulk insertion
|
||||
if (connection.driver.options.type === "sap") {
|
||||
return
|
||||
}
|
||||
|
||||
// Oracle does not support automatic ID generation for bulk inserts, so we manually assign IDs to avoid issues.
|
||||
const isOracle = connection.driver.options.type === "oracle"
|
||||
const values: Partial<User>[] = [
|
||||
{ name: "Umed Khudoiberdiev", memberId: 1 },
|
||||
{
|
||||
name: "Bakhrom Baubekov",
|
||||
memberId: null,
|
||||
} as unknown as Partial<User>, // try setting something NULL (see issue #11362)
|
||||
{ name: "Bakhodur Kandikov", memberId: 3 },
|
||||
].map((user, index) =>
|
||||
isOracle ? { id: index + 1, ...user } : user,
|
||||
)
|
||||
|
||||
await connection
|
||||
.createQueryBuilder()
|
||||
.insert()
|
||||
.into(User)
|
||||
.values([
|
||||
{ name: "Umed Khudoiberdiev" },
|
||||
{ name: "Bakhrom Baubekov" },
|
||||
{ name: "Bakhodur Kandikov" },
|
||||
])
|
||||
.values(values)
|
||||
.execute()
|
||||
|
||||
const users = await connection.getRepository(User).find({
|
||||
@ -91,9 +98,9 @@ describe("query builder > insert", () => {
|
||||
},
|
||||
})
|
||||
users.should.be.eql([
|
||||
{ id: 1, name: "Umed Khudoiberdiev" },
|
||||
{ id: 2, name: "Bakhrom Baubekov" },
|
||||
{ id: 3, name: "Bakhodur Kandikov" },
|
||||
{ id: 1, name: "Umed Khudoiberdiev", memberId: 1 },
|
||||
{ id: 2, name: "Bakhrom Baubekov", memberId: null },
|
||||
{ id: 3, name: "Bakhodur Kandikov", memberId: 3 },
|
||||
])
|
||||
}),
|
||||
))
|
||||
@ -125,31 +132,37 @@ describe("query builder > insert", () => {
|
||||
Promise.all(
|
||||
connections.map(async (connection) => {
|
||||
// this test is skipped for sqlite based drivers because it does not support DEFAULT values in insertions,
|
||||
// also it is skipped for Oracle and SAP because it does not support bulk insertion
|
||||
// also it is skipped for SAP because it does not support bulk insertion
|
||||
if (
|
||||
DriverUtils.isSQLiteFamily(connection.driver) ||
|
||||
connection.driver.options.type === "oracle" ||
|
||||
connection.driver.options.type === "sap"
|
||||
)
|
||||
) {
|
||||
return
|
||||
}
|
||||
|
||||
// Oracle does not support automatic ID generation for bulk inserts, so we manually assign IDs to avoid issues.
|
||||
const isOracle = connection.driver.options.type === "oracle"
|
||||
const values: Partial<Photo>[] = [
|
||||
{
|
||||
url: "1.jpg",
|
||||
counters: {
|
||||
likes: 1,
|
||||
favorites: 1,
|
||||
comments: 1,
|
||||
},
|
||||
},
|
||||
{
|
||||
url: "2.jpg",
|
||||
},
|
||||
].map((photo, index) =>
|
||||
isOracle ? { id: index + 1, ...photo } : photo,
|
||||
)
|
||||
|
||||
await connection
|
||||
.createQueryBuilder()
|
||||
.insert()
|
||||
.into(Photo)
|
||||
.values([
|
||||
{
|
||||
url: "1.jpg",
|
||||
counters: {
|
||||
likes: 1,
|
||||
favorites: 1,
|
||||
comments: 1,
|
||||
},
|
||||
},
|
||||
{
|
||||
url: "2.jpg",
|
||||
},
|
||||
])
|
||||
.values(values)
|
||||
.execute()
|
||||
|
||||
const loadedPhoto1 = await connection
|
||||
|
||||
@ -106,46 +106,6 @@ describe("tree tables > materialized-path", () => {
|
||||
}),
|
||||
))
|
||||
|
||||
it("categories should be attached via children and saved properly", () =>
|
||||
Promise.all(
|
||||
connections.map(async (connection) => {
|
||||
const categoryRepository =
|
||||
connection.getTreeRepository(Category)
|
||||
|
||||
const a1 = new Category()
|
||||
a1.name = "a1"
|
||||
await categoryRepository.save(a1)
|
||||
|
||||
const a11 = new Category()
|
||||
a11.name = "a11"
|
||||
|
||||
const a12 = new Category()
|
||||
a12.name = "a12"
|
||||
|
||||
a1.childCategories = [a11, a12]
|
||||
await categoryRepository.save(a1)
|
||||
|
||||
const rootCategories = await categoryRepository.findRoots()
|
||||
rootCategories.should.be.eql([
|
||||
{
|
||||
id: 1,
|
||||
name: "a1",
|
||||
},
|
||||
])
|
||||
|
||||
const a11Parent = await categoryRepository.findAncestors(a11)
|
||||
a11Parent.length.should.be.equal(2)
|
||||
a11Parent.should.deep.include({ id: 1, name: "a1" })
|
||||
a11Parent.should.deep.include({ id: 2, name: "a11" })
|
||||
|
||||
const a1Children = await categoryRepository.findDescendants(a1)
|
||||
a1Children.length.should.be.equal(3)
|
||||
a1Children.should.deep.include({ id: 1, name: "a1" })
|
||||
a1Children.should.deep.include({ id: 2, name: "a11" })
|
||||
a1Children.should.deep.include({ id: 3, name: "a12" })
|
||||
}),
|
||||
))
|
||||
|
||||
it("categories should be attached via children and saved properly and everything must be saved in cascades", () =>
|
||||
Promise.all(
|
||||
connections.map(async (connection) => {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user