Связь Ajax между клиентом и сервером часто включает данные в формате JSON. В то время как JSON хорошо работает для строк, чисел и логических значений, он может создавать определенные трудности для дат из-за того, как они преобразуются в ASP.NET. Поскольку у них нет специального представления для дат, они сериализуются как простые строки. В качестве решения механизм сериализации по умолчанию ASP.NET Web Forms и MVC сериализует даты в специальной форме - / Date (ticks) / - где тики - это количество миллисекунд с 1 января 1970 года.
Эта проблема может быть решена двумя способами:
клиентская сторона
Преобразование полученной строки даты в число и создание объекта даты с использованием конструктора класса даты с параметрами тиков как параметр. [ ! d5]
function ToJavaScriptDate (значение) {var pattern = / Date \ (([^)] +) \) /; var results = pattern.exec (значение); var dt = new Date (parseFloat (результаты [1])); return (dt.getMonth () + 1) + "/" + dt.getDate () + "/" + dt.getFullYear ();
}
серверная сторона
В предыдущем решении используется сценарий на стороне клиента для преобразования даты в объект JavaScript Date. Вы также можете использовать код на стороне сервера, который сериализует экземпляры .NET DateTime в выбранном вами формате. Для выполнения этой задачи вам необходимо создать свой собственный ActionResult и затем сериализовать данные так, как вы хотите.
ссылка: http://www.developer.com/net/dealing-with-json -dates-в-asp.net-mvc.html
Возможно, вам придется немного уточнить. Чего вы действительно пытаетесь достичь? Если вы действительно хотите узнать имена столбцов, которые содержат только нулевые значения, вам придется пройти через схему и выполнить динамический запрос на основе этого.
Я не знаю, какие СУБД вы используя, поэтому я поставлю здесь псевдокод.
for each col
begin
@cmd = 'if not exists (select * from tablename where ' + col + ' is not null begin print ' + col + ' end'
exec(@cmd)
end
SELECT t.column_name
FROM user_tab_columns t
WHERE t.nullable = 'Y' AND t.table_name = 'table name here' AND t.num_distinct = 0;
Вам нужно будет перебрать набор столбцов и проверить их. Вы должны иметь возможность получить список всех столбцов с командой таблицы DESCRIBE.
Псевдокод:
foreach $column ($cols) {
query("SELECT count(*) FROM table WHERE $column IS NOT NULL")
if($result is zero) {
# $column contains only null values"
push @onlyNullColumns, $column;
} else {
# $column contains non-null values
}
}
return @onlyNullColumns;
Я знаю, что это похоже на малоконтактный, но SQL не предоставляет собственный метод выбора столбцов, только строки.
Если вам нужно перечислить все строки, где все значения столбца NULL
, я бы использовал функцию COLLATE
. Это принимает список значений и возвращает первое ненулевое значение. Если вы добавите все имена столбцов в список, затем используйте IS NULL
, вы должны получить все строки, содержащие только нули.
SELECT * FROM MyTable WHERE COLLATE(Col1, Col2, Col3, Col4......) IS NULL
У вас не должно быть никаких таблиц со ВСЕМИ columns
null, так как это означает, что у вас нет primary key
(не разрешено быть null
). Отсутствие первичного ключа - это то, чего следует избегать; это нарушает первую нормальную форму.
Попробуйте это -
DECLARE @table VARCHAR(100) = 'dbo.table'
DECLARE @sql NVARCHAR(MAX) = ''
SELECT @sql = @sql + 'IF NOT EXISTS(SELECT 1 FROM ' + @table + ' WHERE ' + c.name + ' IS NOT NULL) PRINT ''' + c.name + ''''
FROM sys.objects o
JOIN sys.columns c ON o.[object_id] = c.[object_id]
WHERE o.[type] = 'U'
AND o.[object_id] = OBJECT_ID(@table)
AND c.is_nullable = 1
EXEC(@sql)
Или вы хотите просто увидеть, имеет ли столбец только значения NULL (и, следовательно, вероятно, не используется)?
Дальнейшее разъяснение вопроса может помочь.
EDIT : Хорошо .. вот какой-то действительно грубый код, чтобы вы пошли ...
SET NOCOUNT ON
DECLARE @TableName Varchar(100)
SET @TableName='YourTableName'
CREATE TABLE #NullColumns (ColumnName Varchar(100), OnlyNulls BIT)
INSERT INTO #NullColumns (ColumnName, OnlyNulls) SELECT c.name, 0 FROM syscolumns c INNER JOIN sysobjects o ON c.id = o.id AND o.name = @TableName AND o.xtype = 'U'
DECLARE @DynamicSQL AS Nvarchar(2000)
DECLARE @ColumnName Varchar(100)
DECLARE @RC INT
SELECT TOP 1 @ColumnName = ColumnName FROM #NullColumns WHERE OnlyNulls=0
WHILE @@ROWCOUNT > 0
BEGIN
SET @RC=0
SET @DynamicSQL = 'SELECT TOP 1 1 As HasNonNulls FROM ' + @TableName + ' (nolock) WHERE ''' + @ColumnName + ''' IS NOT NULL'
EXEC sp_executesql @DynamicSQL
set @RC=@@rowcount
IF @RC=1
BEGIN
SET @DynamicSQL = 'UPDATE #NullColumns SET OnlyNulls=1 WHERE ColumnName=''' + @ColumnName + ''''
EXEC sp_executesql @DynamicSQL
END
ELSE
BEGIN
SET @DynamicSQL = 'DELETE FROM #NullColumns WHERE ColumnName=''' + @ColumnName+ ''''
EXEC sp_executesql @DynamicSQL
END
SELECT TOP 1 @ColumnName = ColumnName FROM #NullColumns WHERE OnlyNulls=0
END
SELECT * FROM #NullColumns
DROP TABLE #NullColumns
SET NOCOUNT OFF
Да, есть более простые способы, но у меня есть встреча, чтобы идти прямо сейчас. Удачи!
Вы можете сделать:
select
count(<columnName>)
from
<tableName>
Если счетчик возвращает 0, это означает, что все строки в этом столбце имеют все NULL (или в таблице нет всех строк)
можно изменить на
select
case(count(<columnName>)) when 0 then 'Nulls Only' else 'Some Values' end
from
<tableName>
Если вы хотите его автоматизировать, вы можете использовать системные таблицы для итерации имен столбцов в интересующей вас таблице
Это должно дать вам список всех столбцов в таблице «Человек», который имеет только NULL-значения. Вы получите результаты как несколько наборов результатов, которые либо пусты, либо содержат имя одного столбца. Вам нужно заменить «Person» в двух местах, чтобы использовать его с другой таблицей.
DECLARE crs CURSOR LOCAL FAST_FORWARD FOR SELECT name FROM syscolumns WHERE id=OBJECT_ID('Person')
OPEN crs
DECLARE @name sysname
FETCH NEXT FROM crs INTO @name
WHILE @@FETCH_STATUS = 0
BEGIN
EXEC('SELECT ''' + @name + ''' WHERE NOT EXISTS (SELECT * FROM Person WHERE ' + @name + ' IS NOT NULL)')
FETCH NEXT FROM crs INTO @name
END
CLOSE crs
DEALLOCATE crs
Я также рекомендовал бы искать поля, все из которых имеют одинаковое значение, а не только NULL.
То есть для каждого столбца в каждой таблице выполняется запрос:
SELECT COUNT(DISTINCT field) FROM tableName
и сосредоточиться на тех, которые в результате возвращают 1.
Обновленная версия версии «user2466387» с дополнительным небольшим тестом, который может повысить производительность, потому что бесполезно тестировать столбцы с нулевым значением:
AND IS_NULLABLE = 'YES'
Полный код:
SET NOCOUNT ON;
DECLARE
@ColumnName sysname
,@DataType nvarchar(128)
,@cmd nvarchar(max)
,@TableSchema nvarchar(128) = 'dbo'
,@TableName sysname = 'TableName';
DECLARE getinfo CURSOR FOR
SELECT
c.COLUMN_NAME
,c.DATA_TYPE
FROM
INFORMATION_SCHEMA.COLUMNS AS c
WHERE
c.TABLE_SCHEMA = @TableSchema
AND c.TABLE_NAME = @TableName
AND IS_NULLABLE = 'YES';
OPEN getinfo;
FETCH NEXT FROM getinfo INTO @ColumnName, @DataType;
WHILE @@FETCH_STATUS = 0
BEGIN
SET @cmd = N'IF NOT EXISTS (SELECT * FROM ' + @TableSchema + N'.' + @TableName + N' WHERE [' + @ColumnName + N'] IS NOT NULL) RAISERROR(''' + @ColumnName + N' (' + @DataType + N')'', 0, 0) WITH NOWAIT;';
EXECUTE (@cmd);
FETCH NEXT FROM getinfo INTO @ColumnName, @DataType;
END;
CLOSE getinfo;
DEALLOCATE getinfo;
Вот обновленная версия запроса Брайана за 2008 год и позже. Он использует INFORMATION_SCHEMA.COLUMNS, добавляет переменные для схемы таблицы и имени таблицы. Тип данных столбца был добавлен в вывод. Включение типа данных столбца помогает при поиске столбца определенного типа данных. Я не добавил ширины столбцов или что-то в этом роде.
Для вывода используется RAISERROR ... WITH NOWAIT, поэтому текст будет отображаться сразу, а не сразу (по большей части) в конце, как PRINT ..
SET NOCOUNT ON;
DECLARE
@ColumnName sysname
,@DataType nvarchar(128)
,@cmd nvarchar(max)
,@TableSchema nvarchar(128) = 'dbo'
,@TableName sysname = 'TableName';
DECLARE getinfo CURSOR FOR
SELECT
c.COLUMN_NAME
,c.DATA_TYPE
FROM
INFORMATION_SCHEMA.COLUMNS AS c
WHERE
c.TABLE_SCHEMA = @TableSchema
AND c.TABLE_NAME = @TableName;
OPEN getinfo;
FETCH NEXT FROM getinfo INTO @ColumnName, @DataType;
WHILE @@FETCH_STATUS = 0
BEGIN
SET @cmd = N'IF NOT EXISTS (SELECT * FROM ' + @TableSchema + N'.' + @TableName + N' WHERE [' + @ColumnName + N'] IS NOT NULL) RAISERROR(''' + @ColumnName + N' (' + @DataType + N')'', 0, 0) WITH NOWAIT;';
EXECUTE (@cmd);
FETCH NEXT FROM getinfo INTO @ColumnName, @DataType;
END;
CLOSE getinfo;
DEALLOCATE getinfo;
На самом деле не уверен в 2005 году, но 2008 год съел его:
USE [DATABASE_NAME] -- !
GO
DECLARE @SQL NVARCHAR(MAX)
DECLARE @TableName VARCHAR(255)
SET @TableName = 'TABLE_NAME' -- !
SELECT @SQL =
(
SELECT
CHAR(10)
+'DELETE FROM ['+t1.TABLE_CATALOG+'].['+t1.TABLE_SCHEMA+'].['+t1.TABLE_NAME+'] WHERE '
+(
SELECT
CASE t2.ORDINAL_POSITION
WHEN (SELECT MIN(t3.ORDINAL_POSITION) FROM INFORMATION_SCHEMA.COLUMNS t3 WHERE t3.TABLE_NAME=t2.TABLE_NAME) THEN ''
ELSE 'AND '
END
+'['+COLUMN_NAME+'] IS NULL' AS 'data()'
FROM INFORMATION_SCHEMA.COLUMNS t2 WHERE t2.TABLE_NAME=t1.TABLE_NAME FOR XML PATH('')
) AS 'data()'
FROM INFORMATION_SCHEMA.TABLES t1 WHERE t1.TABLE_NAME = @TableName FOR XML PATH('')
)
SELECT @SQL -- EXEC(@SQL)
NOT
из запроса внутриWHILE
, и вы получите список столбцов, имеющих по крайней мере 1 запись со значением. – funkwurm 20 August 2014 в 14:51