Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
 Доработать запрос определения пустых column в таблице  [new]
Jhonny-2005
Member

Откуда: Москва
Сообщений: 72
В общем суть такая - нужно определить пустые column в таблице MBAnalit.
Знаю, что как то коряво сделал, но суть в этой корявости в том, что в курсоре ненормально как то отрабатывает такое сравнение
if @RecordCount = (select count(*) from MBAnalit WHERE @Param is null)
Методом тыка определил, что почему то получается 0 в запросе, т.е. таким методом:
Declare @a NVARCHAR(50)
set @a = 'test10'
select count(1) from MBAnalit WHERE test10 is null
select count(1) from MBAnalit WHERE @a is null
exec('select count(1) from MBAnalit WHERE ' + @a + ' is null')
первый селект - 25577, второй 0, третий 25577.

Вопрос к гуру, как правильно доделать, чтобы сие сравнение корректно отрабатывало?


-- кол-во записей в таблице 
DECLARE @RecordCount int 
SET @RecordCount = (select count(1) from MBAnalit) 
-- переменная для имени поля MBAnalut 
DECLARE @Param NVARCHAR(50) 
DECLARE Cur1 CURSOR SCROLL 
FOR 
  -- получить список всех полей MBAnalit 
  SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.[COLUMNS] WHERE TABLE_NAME = 'MBAnalit' and COLUMN_NAME in (select FldName from mbrecvan where ExistFld = 'Е')  

OPEN Cur1 
FETCH NEXT FROM Cur1 INTO @Param 
WHILE @@FETCH_STATUS = 0 BEGIN 
        -- Если Кол-во записей = null по текущему полю равно общему кол-ву то вывести реквизит на экран 
		if @RecordCount = (select count(*) from MBAnalit WHERE @Param is null) 
                print @param 
        -- следующий шаг цикла 
        FETCH NEXT FROM Cur1 INTO @Param 
END 
CLOSE Cur1 
DEALLOCATE Cur1
14 янв 16, 17:29    [18679780]     Ответить | Цитировать Сообщить модератору
 Re: Доработать запрос определения пустых column в таблице  [new]
Glory
Member

Откуда:
Сообщений: 104751
Jhonny-2005
первый селект - 25577, второй 0, третий 25577.

Потому что второй запрос эквивалентен
select count(1) from MBAnalit WHERE 'test10' is null
14 янв 16, 17:35    [18679827]     Ответить | Цитировать Сообщить модератору
 Re: Доработать запрос определения пустых column в таблице  [new]
Jhonny-2005
Member

Откуда: Москва
Сообщений: 72
Glory, оп, чтот не знал, честно говоря такого. И как можно обыграть это?
14 янв 16, 17:39    [18679860]     Ответить | Цитировать Сообщить модератору
 Re: Доработать запрос определения пустых column в таблице  [new]
o-o
Guest
динамику писать, как еще-то строковую переменную с названием столбца в запрос влепить
14 янв 16, 17:41    [18679875]     Ответить | Цитировать Сообщить модератору
 Re: Доработать запрос определения пустых column в таблице  [new]
Jhonny-2005
Member

Откуда: Москва
Сообщений: 72
o-o,

К сожалению не силен в этом
14 янв 16, 17:48    [18679936]     Ответить | Цитировать Сообщить модератору
 Re: Доработать запрос определения пустых column в таблице  [new]
o-o
Guest
create table dbo.t (col int);
go
insert into dbo.t
values (1), (null), (2);
go

declare @Param NVARCHAR(50) = 'col'; 
select count(*) from dbo.t WHERE @Param is null;
-- 0

declare @sql varchar(8000) = 'select count(*) from dbo.t WHERE ' + @Param + ' is null';
exec (@sql);
-- 1
14 янв 16, 18:01    [18680040]     Ответить | Цитировать Сообщить модератору
 Re: Доработать запрос определения пустых column в таблице  [new]
Jhonny-2005
Member

Откуда: Москва
Сообщений: 72
o-o,
Спасибо за пример. Но допустим, сейчас у меня выводятся все поля по количеству, т.е.
25576
22978
25577
25577
и т.д.
Теперь как их можно сравнить, т.к. у нас же в @sql хранится именно строка 'select count(*) from dbo.MBAnalit WHERE ' + @Param + ' is null
Нужно по сути после сравнения получить:
Имя поля, у которого count(*) равен общему (select count(1) from MBAnalit)

Прошу простить, если туплю, задача вроде простая, но что то 3 дня воюю.


-- кол-во записей в таблице 
DECLARE @RecordCount int 
DECLARE @RC int 
SET @RecordCount = (select count(1) from MBAnalit) 
-- переменная для имени поля MBAnalut 
DECLARE @Param NVARCHAR(50) 
DECLARE Cur1 CURSOR SCROLL 
FOR 
  -- получить список всех полей-реквизитов MBAnalit 
  SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.[COLUMNS] WHERE TABLE_NAME = 'MBAnalit' and COLUMN_NAME in (select FldName from mbrecvan where ExistFld = 'Е')  

OPEN Cur1 
FETCH NEXT FROM Cur1 INTO @Param 
WHILE @@FETCH_STATUS = 0 BEGIN 
		declare @sql varchar(8000) = 'select count(*) from dbo.MBAnalit WHERE ' + @Param + ' is null'
		exec (@sql)

        FETCH NEXT FROM Cur1 INTO @Param 
END 
CLOSE Cur1 
DEALLOCATE Cur1
15 янв 16, 08:01    [18681721]     Ответить | Цитировать Сообщить модератору
 Re: Доработать запрос определения пустых column в таблице  [new]
LexusR
Member

Откуда: Novosibirsk
Сообщений: 1887
Jhonny-2005,
-- кол-во записей в таблице 
DECLARE @RecordCount int 
DECLARE @RC int 
SET @RecordCount = (select count(1) from MBAnalit) 
-- переменная для имени поля MBAnalut 
DECLARE @Param NVARCHAR(50) 
DECLARE Cur1 CURSOR SCROLL 
FOR 
  -- получить список всех полей-реквизитов MBAnalit 
  SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.[COLUMNS] WHERE TABLE_NAME = 'MBAnalit' and COLUMN_NAME in (select FldName from mbrecvan where ExistFld = 'Е')  

OPEN Cur1 
FETCH NEXT FROM Cur1 INTO @Param 
WHILE @@FETCH_STATUS = 0 BEGIN 
		declare @sql varchar(8000) = 'select ''' + @Param + ''' as [EmptyParam] if not exists(select * from dbo.MBAnalit WHERE ' + @Param + ' is not null)'
		exec (@sql)

        FETCH NEXT FROM Cur1 INTO @Param 
END 
CLOSE Cur1 
DEALLOCATE Cur1
15 янв 16, 08:59    [18681875]     Ответить | Цитировать Сообщить модератору
 Re: Доработать запрос определения пустых column в таблице  [new]
Jhonny-2005
Member

Откуда: Москва
Сообщений: 72
Jhonny-2005,

В общем то получилось сейчас такое. Осталось понять, как убрать лишнее, т.е. как выполнить сравнение и отсечь все лишнее. Думаю может это во временную таблицу все распихать, и потом уже делать из неё сравнение:
-- кол-во записей в таблице 
DECLARE @RecordCount int 
DECLARE @RC int 
SET @RecordCount = (select count(1) from MBAnalit) 
-- переменная для имени поля MBAnalit 
DECLARE @Param NVARCHAR(50) 
DECLARE Cur1 CURSOR SCROLL 
FOR 
  -- получить список всех полей-реквизитов MBAnalit 
  SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.[COLUMNS] WHERE TABLE_NAME = 'MBAnalit' and COLUMN_NAME in (select FldName from mbrecvan where ExistFld = 'Е')  

OPEN Cur1 
FETCH NEXT FROM Cur1 INTO @Param 
WHILE @@FETCH_STATUS = 0 BEGIN 
		
		declare @sql varchar(8000) = 'select count(*) ' + @Param + ' from dbo.MBAnalit WHERE ' + @Param + ' is null '
		exec (@sql)
		FETCH NEXT FROM Cur1 INTO @Param 
END 
CLOSE Cur1 
DEALLOCATE Cur1
15 янв 16, 09:01    [18681882]     Ответить | Цитировать Сообщить модератору
 Re: Доработать запрос определения пустых column в таблице  [new]
LexusR
Member

Откуда: Novosibirsk
Сообщений: 1887
LexusR, сорри
DECLARE @RecordCount int 
DECLARE @RC int 
SET @RecordCount = (select count(1) from MBAnalit) 
-- переменная для имени поля MBAnalut 
DECLARE @Param NVARCHAR(50) 
DECLARE Cur1 CURSOR SCROLL 
FOR 
  -- получить список всех полей-реквизитов MBAnalit 
  SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.[COLUMNS] WHERE TABLE_NAME = 'MBAnalit' and COLUMN_NAME in (select FldName from mbrecvan where ExistFld = 'Е')  

OPEN Cur1 
FETCH NEXT FROM Cur1 INTO @Param 
WHILE @@FETCH_STATUS = 0 BEGIN 
		declare @sql varchar(8000) = 'select ''' + @Param + ''' as [EmptyParam] WHERE not exists(select * from dbo.MBAnalit WHERE ' + @Param + ' is not null)'
		exec (@sql)

        FETCH NEXT FROM Cur1 INTO @Param 
END 
CLOSE Cur1 
DEALLOCATE Cur1
15 янв 16, 09:01    [18681888]     Ответить | Цитировать Сообщить модератору
 Re: Доработать запрос определения пустых column в таблице  [new]
LexusR
Member

Откуда: Novosibirsk
Сообщений: 1887
Jhonny-2005,

Список пустых колонок
DECLARE @SQL VARCHAR(8000)
SELECT @SQL = ISNULL(@SQL +' UNION SELECT ',' SELECT ')+ ''''+COLUMN_NAME+''' AS [EmptyParam]  WHERE NOT EXISTS(SELECT * FROM dbo.MBAnalit WHERE '+COLUMN_NAME+' IS NOT NULL)' 
FROM INFORMATION_SCHEMA.[COLUMNS] WHERE TABLE_NAME = 'MBAnalit'  and COLUMN_NAME in (select FldName from mbrecvan where ExistFld = 'Е')  

EXEC(@SQL)
15 янв 16, 09:25    [18681964]     Ответить | Цитировать Сообщить модератору
 Re: Доработать запрос определения пустых column в таблице  [new]
Jhonny-2005
Member

Откуда: Москва
Сообщений: 72
LexusR,
Спасибо. Проблема в целом решилась твоим предыдущим запросом.
Но последний запрос интересен, но почему то странно не отрабатывает с ошибкой:
Msg 102, Level 15, State 1, Line 1
Incorrect syntax near 'WHE'.
15 янв 16, 10:31    [18682360]     Ответить | Цитировать Сообщить модератору
 Re: Доработать запрос определения пустых column в таблице  [new]
Jhonny-2005
Member

Откуда: Москва
Сообщений: 72
LexusR,
Посмотрел запрос, который выдает @SQL, слишком длинный чтоли, обрывается на WHE
15 янв 16, 10:33    [18682366]     Ответить | Цитировать Сообщить модератору
 Re: Доработать запрос определения пустых column в таблице  [new]
Jhonny-2005
Member

Откуда: Москва
Сообщений: 72
В общем то всем спасибо.
Итог - такой запрос:
DECLARE @RecordCount int 
DECLARE @RC int 
SET @RecordCount = (select count(1) from MBAnalit)   

CREATE TABLE #EmptyRequisites (REQUISITE_NAME NVARCHAR(50) null) 

-- переменная для имени поля MBAnalut 
DECLARE @Param NVARCHAR(50) 
DECLARE Cur1 CURSOR SCROLL 
FOR 
  -- получить список всех полей-реквизитов MBAnalit 
  SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.[COLUMNS] WHERE TABLE_NAME = 'MBAnalit' and COLUMN_NAME in (select FldName from mbrecvan where ExistFld = 'Е') 

  ORDER BY ORDINAL_POSITION desc 
   

OPEN Cur1 
FETCH NEXT FROM Cur1 INTO @Param 
WHILE @@FETCH_STATUS = 0 
BEGIN 
        declare @sql varchar(8000) = 'IF EXISTS( 
                select ''' + @Param + ''' as [Пустой реквизит] WHERE not exists(select * from dbo.MBAnalit WHERE ' + @Param + ' is not null)    )

                        insert into #EmptyRequisites select ''' + @Param + ''' as [Пустой реквизит] WHERE not exists(select * from dbo.MBAnalit WHERE ' + @Param + ' is not null) 

                        ' 
        exec (@sql) 
        
        FETCH NEXT FROM Cur1 INTO @Param 
END 
CLOSE Cur1 
DEALLOCATE Cur1 

SELECT * FROM #EmptyRequisites
DROP TABLE #EmptyRequisites
15 янв 16, 10:56    [18682535]     Ответить | Цитировать Сообщить модератору
 Re: Доработать запрос определения пустых column в таблице  [new]
LexusR
Member

Откуда: Novosibirsk
Сообщений: 1887
Jhonny-2005,
если сервер позволяет поменяй varchar(8000) на varchar(max)
DECLARE @SQL VARCHAR(max)
SELECT @SQL = ISNULL(@SQL +' UNION SELECT ',' SELECT ')+ ''''+COLUMN_NAME+''' AS [EmptyParam]  WHERE NOT EXISTS(SELECT * FROM dbo.MBAnalit WHERE '+COLUMN_NAME+' IS NOT NULL)' 
FROM INFORMATION_SCHEMA.[COLUMNS] WHERE TABLE_NAME = 'MBAnalit' --and COLUMN_NAME in (select FldName from mbrecvan where ExistFld = 'Е')  

EXEC(@SQL)
15 янв 16, 11:04    [18682609]     Ответить | Цитировать Сообщить модератору
 Re: Доработать запрос определения пустых column в таблице  [new]
LexusR
Member

Откуда: Novosibirsk
Сообщений: 1887
LexusR
Jhonny-2005,
если сервер позволяет поменяй varchar(8000) на varchar(max)

DECLARE @SQL VARCHAR(max)
SELECT @SQL = ISNULL(@SQL +' UNION SELECT ',' SELECT ')+ ''''+COLUMN_NAME+''' AS [EmptyParam]  WHERE NOT EXISTS(SELECT * FROM dbo.MBAnalit WHERE '+COLUMN_NAME+' IS NOT NULL)' 
FROM INFORMATION_SCHEMA.[COLUMNS] WHERE TABLE_NAME = 'MBAnalit'  and COLUMN_NAME in (select FldName from mbrecvan where ExistFld = 'Е')  

EXEC(@SQL)
15 янв 16, 11:06    [18682625]     Ответить | Цитировать Сообщить модератору
 Re: Доработать запрос определения пустых column в таблице  [new]
Jhonny-2005
Member

Откуда: Москва
Сообщений: 72
LexusR,

Благодарю. То, что было нужно в сжатом запросе.
15 янв 16, 11:39    [18682918]     Ответить | Цитировать Сообщить модератору
 Re: Доработать запрос определения пустых column в таблице  [new]
invm
Member

Откуда: Москва
Сообщений: 9836
За один проход по таблице:
use tempdb;
go

create table dbo.t (c1 int, c2 int, c3 int, c4 int);
insert into dbo.t
values
 (1, null, 1, null),
 (1, null, 1, null),
 (1, null, 1, null),
 (1, null, 1, null);
go

declare @table sysname = N'dbo.t', @s nvarchar(max)

select
 @s = N';with s as (select ' + stuff(a.x.value('.', 'nvarchar(max)'), 1, 2, '') + N' from ' + @table + N') select u.c from s unpivot (c for columns in (' + stuff(b.x.value('.', 'nvarchar(max)'), 1, 2, '') + N')) u'
from
 (select N', case when count(' + quotename(COLUMN_NAME) + N') = 0 then ' + quotename(COLUMN_NAME, '''') + N' end as ' + quotename(COLUMN_NAME) from INFORMATION_SCHEMA.COLUMNS where TABLE_NAME = N't' and TABLE_SCHEMA = N'dbo' for xml path(''), type) a(x) cross join
 (select N', ' + quotename(COLUMN_NAME) from INFORMATION_SCHEMA.COLUMNS where TABLE_NAME = parsename(@table, 1) and TABLE_SCHEMA = parsename(@table, 2) for xml path(''), type) b(x);

select @s;
exec(@s);
go

drop table dbo.t;
go
15 янв 16, 12:24    [18683290]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить