Основываясь на этом ответе , я создал функцию для циклического перебора имен столбцов и возврата результата запроса в формат JSON. Я использую FOR XML, потому что я работаю над версией SQL Server, которая не поддерживает FOR JSON.
У меня есть запрос, возвращающий допустимый формат JSON, за исключением случаев, когда есть поля даты, и хотя я искал в ИнтернетеЯ думаю, что я немного над головой с точки зрения глубины понимания SQL Server. Я играл с CAST
и CONVERT
и ISDATE
, но не могу получить запрос для получения результатов. Мне также немного непонятно, как работает value('.', 'varchar(max)')
, хотя я уже прочитал его.
Например, этот запрос отлично работает.
SELECT
STUFF((
SELECT',{"account_no":"' + account_no + '"' + ',"version_num":"' + version_num + '"' + ',"user_id":"' + user_id + '"' + '}'
FROM uAccountHighLevel
WHERE account_no='3718035' and version_num='37'
FOR XML path(''), type).value('.', 'varchar(max)')
, 1, 1, '')
Возвращение
{"account_no":"3718035","version_num":"37","user_id":"Sholtzman"}
Однако, когда я добавляю поле datetime (или date) в запрос, происходит следующее сообщение:
Conversion failed when converting date and/or time from character string.
См. Запрос с добавленным полем datetime:
SELECT
STUFF((
SELECT',{"account_no":"' + account_no + '"' + ',"version_num":"' + version_num + '"' + ',"user_id":"' + user_id + '"' + ',"time_stamp":"' + time_stamp + '"' + '}'
FROM uAccountHighLevel
WHERE account_no='3718035' and version_num='37'
FOR XML path(''), type).value('.', 'varchar(max)')
, 1, 1, '')
Вот снимок таблицы, с которой я работаю. Все таблицы имеют одинаковое сочетание типов данных:
Если бы значения полей были известны каждый раз, думаю, я мог бы решить это, но функцияэто создает этот запрос, будет многократно использоваться во многих таблицах, поэтому поле даты / даты и времени может появляться в любом порядке, поэтому мне нужна эта функция, чтобы каким-то образом создать для обработки полей даты и времени. У меня также нет контроля над изменением типов данных в базе данных.
Ниже приведен код vba, который я использую для создания JSON.
Sub querySQL()
Dim conn As ADODB.Connection
Set conn = New ADODB.Connection
conn.Open "Provider=SQLOLEDB;Data Source=DVW-SQL02;Initial Catalog=UniversalQuoteProposal;UID=SVC_UQP;PWD=$vc13#up"
'grab column names
Dim sql As String
sql = "SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = N'uAccountHighLevel'"
Dim rs As ADODB.Recordset
Set rs = New ADODB.Recordset
With rs
.ActiveConnection = conn
.CursorLocation = adUseClient
.Open sql, conn, adOpenKeyset, adLockReadOnly, adCmdText
End With
sql = buildSQL("uAccountHighLevel", rs, "List")
Dim rsFinal As ADODB.Recordset
Set rsFinal = New ADODB.Recordset
With rsFinal
.ActiveConnection = conn
.CursorLocation = adUseClient
.Open sql, conn, adOpenKeyset, adLockReadOnly, adCmdText
Debug.Print .Fields(0).Value
End With
End Sub
Function buildSQL(theTable As String, rs As ADODB.Recordset, arrayOrList As String) As String
'this has to be fixed, but we can do it :)
'adjust query builder and also had a case for isdate to cast to string
Dim queryBuilder As String
queryBuilder = "SELECT "
If arrayOrList = "array" Then queryBuilder = queryBuilder & "'[' + "
queryBuilder = queryBuilder & "STUFF(("
queryBuilder = queryBuilder & "SELECT',{"
rs.MoveFirst
Dim f As Long
For f = 0 To 3 'rs.RecordCount - 1
queryBuilder = queryBuilder & """" & rs.Fields(0).Value & """:""' + " & rs.Fields(0).Value & " + '""' + ',"
'this is one of my attempts to play with isdate, cast, convert
'queryBuilder = queryBuilder & """" & rs.Fields(0).Value & """:""' + (CASE WHEN ISDATE(" & rs.Fields(0).Value & ") = 1 THEN CONVERT(datetime, cast([" & rs.Fields(0) & "] AS CHAR(8))) END) + '""' + ',"
rs.MoveNext
Next
queryBuilder = Left(queryBuilder, Len(queryBuilder) - 1) & "}'"
queryBuilder = queryBuilder & " FROM " & theTable & " WHERE account_no='3718035' and version_num='37' "
queryBuilder = queryBuilder & " for xml path(''), type"
queryBuilder = queryBuilder & ").value('.', 'varchar(max)'), 1, 1, '')"
If arrayOrList = "array" Then queryBuilder = queryBuilder & " + ']'"
buildSQL = queryBuilder
End Function