Can't select, update or delete from a table because of a 'JSON text is not properly formatted... ' error in SQL Server

zc0qhyus  于 12个月前  发布在  Perl
关注(0)|答案(2)|浏览(201)

For the first 3 statements below, the select/delete/update are causing an error:
"JSON text is not properly formatted. Unexpected character '.' is found at position 0."

I don't know why since I am not using any JSON functions. I expect the select to get data as is and the delete and update statements to just do their work regardless of any JSON data in any column.

The ISJSON is returning 1 for the UserPreferences column since this is the only column that might have json data based on the insert statement.

I'm using SQL Server 2019. This table is a copy of a table from the WideWorldImporters sample database.

Any idea why the first 3 statements are failing?

Also, is there a quick way to find which column is causing it without a separate select for each column?

SELECT * 
FROM Application.People p 
WHERE p.PersonID = 1  -- error

UPDATE Application.People 
SET UserPreferences = NULL 
WHERE PersonID = 1 -- error

DELETE FROM Application.People  -- error

SELECT ISJSON(p.UserPreferences) 
FROM Application.People p 
WHERE p.PersonID = 1 -- = 1

SELECT p.UserPreferences 
FROM Application.People p 
WHERE p.PersonID = 1 -- returns a value

Insert statement and Table's DDL:

INSERT INTO Application.People (PersonID, FullName, PreferredName, IsPermittedToLogon, LogonName, IsExternalLogonProvider, IsSystemUser, IsEmployee, IsSalesperson, UserPreferences, PhoneNumber, FaxNumber, EmailAddress, CustomFields, LastEditedBy)  
VALUES ('1', 'Data Conversion Only', 'Data Conversion Only', 'False', 'NO LOGON', 'False', 'False', 'False', 'False', '{"theme":"blitzer","dateFormat":"yy-mm-dd","timeZone": "PST","table":{"pagingType":"full_numbers","pageLength": 25},"favoritesOnDashboard":true}', '', '', '', '', '1');

CREATE TABLE [Application].[People]
(
    [PersonID] [int] NOT NULL,
    [FullName] [nvarchar](50) NOT NULL,
    [PreferredName] [nvarchar](50) NOT NULL,
    [SearchName]  AS (CONCAT([PreferredName],N' ',[FullName])) PERSISTED NOT NULL,
    [IsPermittedToLogon] [bit] NOT NULL,
    [LogonName] [nvarchar](50) NULL,
    [IsExternalLogonProvider] [bit] NOT NULL,
    [HashedPassword] [varbinary](max) NULL,
    [IsSystemUser] [bit] NOT NULL,
    [IsEmployee] [bit] NOT NULL,
    [IsSalesperson] [bit] NOT NULL,
    [UserPreferences] [nvarchar](max) NULL,
    [PhoneNumber] [nvarchar](20) NULL,
    [FaxNumber] [nvarchar](20) NULL,
    [EmailAddress] [nvarchar](256) NULL,
    [Photo] [varbinary](max) NULL,
    [CustomFields] [nvarchar](max) NULL,
    [OtherLanguages]  AS (json_query([CustomFields],N'$.OtherLanguages')),
    [LastEditedBy] [int] NOT NULL,
    [ValidFrom] [datetime2](7) GENERATED ALWAYS AS ROW START NOT NULL,
    [ValidTo] [datetime2](7) GENERATED ALWAYS AS ROW END NOT NULL,

    CONSTRAINT [PK_Application_People] 
        PRIMARY KEY CLUSTERED ([PersonID] ASC)
                WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, 
                      IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, 
                      ALLOW_PAGE_LOCKS = ON, OPTIMIZE_FOR_SEQUENTIAL_KEY = OFF) ON [USERDATA],
        PERIOD FOR SYSTEM_TIME ([ValidFrom], [ValidTo])
) ON [USERDATA] TEXTIMAGE_ON [USERDATA]
WITH
(SYSTEM_VERSIONING = ON (HISTORY_TABLE = [Application].[People_Archive]))
GO

ALTER TABLE [Application].[People] 
    ADD CONSTRAINT [DF_Application_People_PersonID]  
        DEFAULT (NEXT VALUE FOR [Sequences].[PersonID]) FOR [PersonID]
GO

ALTER TABLE [Application].[People]  WITH CHECK 
    ADD CONSTRAINT [FK_Application_People_Application_People] 
        FOREIGN KEY([LastEditedBy])
        REFERENCES [Application].[People] ([PersonID])
GO

ALTER TABLE [Application].[People] CHECK CONSTRAINT [FK_Application_People_Application_People]
GO
nvbavucw

nvbavucw1#

Your computed column definition is causing problems.

[OtherLanguages]  AS (json_query([CustomFields], N'$.OtherLanguages'))

If a value in the table is not valid JSON then this will error. Note that an empty string '' is not valid JSON, you should use NULL instead.

You must ensure this can't happen, so use CASE and ISJSON to short-circuit.

[OtherLanguages]  AS (CASE WHEN ISJSON([CustomFields]) = 1 THEN JSON_QUERY([CustomFields], N'$.OtherLanguages') END)

You may instead want to add a constraint to ensure it's valid JSON

ALTER TABLE [Application].[People]
ADD CONSTRAINT CustomFields_IsJson
  CHECK (ISJSON([CustomFields]) = 1);
avwztpqn

avwztpqn2#

The select error was because of a computed column that used the json_query function on another column which had an empty string.

The delete and update errors were due to the temporal table Application.People. When I dropped the history table, the errors went out. I am guessing it's related to the computed column. The database is on my dev machine and I don't care about history tables.

相关问题