column name as a parameter

10 отговора 848 прегледа
#1

column name as a parameter

Тук се мъча с една задачка и вече ми писна да ровя из хелпове, някой дали има идея?

Искам да използвам стойност от една клетка като име на поле във друг селект.

select *
from table_1
where (
select <field_1_1>
from table_2
where field_2_pk = field_1_2
) = 0

където field_1_1 е поле в table_1, а това поле приема стойност което е име на поле в table_2

идеята е че в table_2 имам матрица като в едната посока са потребители, в другата (полетата) са определен критерий, а field_1_1 от table_1 приема задължително този критерий. А в table_1 са записите които искам да проверя спрямо този критерий.

Отговор
в отговор на bultra #2

Re: column name as a parameter

Не вярвам да стане само със заявка.
По скоро може със съхранена процедура.

Уеб хостинг и домейн имена от [линк]
Отговор
в отговор на bultra #3

Re: Нормализирай

Това което се опитваш да правиш показва, че структурата на таблиците е генерално сбъркана

salle.online.bg/sig
Отговор
в отговор на salle #4

Re: Нормализирай

Така погледнато и извадено от контекста си прав.
Но и аз съм прав за себе си
Всъщност това е специфичен контрол който е върху съществуваща ERP система, а системата го няма като базова функционалност, и затова така се получава, т.е. не съм правил аз дизайна на базата, а правя контрол в пасивен режим и вадя определени записи в отделен отчет.

Отговор
в отговор на bultra #5

Re: column name as a parameter

Не казваш базата
Ако ти позволява, можеш да ползваш ...where ( select case when ...
или съответната за базата ти конструкция.

Отговор
в отговор на bultra #6

Re: column name as a parameter

Пробвай да "обърнаеш" cross-tab-а с UNION-и така някак:
SELECT  *

FROM table_1
WHERE EXISTS (SELECT <field_1_1>
FROM (
SELECT field_2_pk,
, 'field_1_val1' AS ColumnName
, field_1_val1 AS Value
FROM table_2
UNION ALL
SELECT field_2_pk,
, 'field_1_val2'
, field_1_val2
FROM table_2
UNION ALL
SELECT field_2_pk,
, 'field_1_val3'
, field_1_val3
FROM table_2
...
) s
WHERE s.field_2_pk = field_1_2
AND s.ColumnName = field_1_1
AND s.Value = 0
)

cheers,
</wqw>

Отговор
в отговор на wqw #7

Re: column name as a parameter

Е, да, но така се губи идеята за динамично предаване на името на колоната като параметър

Отговор
в отговор на wqw #8

Re: column name as a parameter

Мисля си за едно "по-интелигентно" решение, като създам функция с входни параметри които идентифицират клетката, която да проверява във втората таблица.

CREATE FUNCTION fun (@cc VARCHAR(20), @uid VARCHAR(20))
RETURNS TINYINT
AS
BEGIN
DECLARE @fun tinyint,
@query1 NVARCHAR(1000)

SET @query1 = NULL
SELECT @query1 = 'IF (SELECT TOP1 '+@cc+' FROM table1 WHERE table1.user_id = '+@uid+
') = 0 SET @fun = 0 ELSE SET @fun = 1'
exec dbo.sp_executesql @query1

RETURN(@fun)
END

която работи чудесно, но когато след това извикам

SELECT *
FROM table2
WHERE dbo.fun(column_cc, column_uid) = 0

ми връща

Server: Msg 557, Level 16, State 2, Procedure is_cc_ok, Line 11
Only functions and extended stored procedures can be executed from within a function.

Къде бъркам?

Отговор
в отговор на bultra #9

Re: column name as a parameter

Трябва сам да си отговарям:
То си пише
във функция не може да се изпълнява скрипт.
решението е функцията да връща сами я скрипт като текст, а не резултата от изпълнението на скрипта, а функцията се подава за изпълнение във външен селект

Отговор
в отговор на bultra #10

Re: column name as a parameter

Точна така, но и не само -- в динамичния SQL не можеш да SET-ваш променливи от caller namespace-а.

salle ти го каза -- сбъркан дизайн на base таблицата. Най-елегантно можеш да излезеш от ситуацията като направиш view което да се базира на cross-tab-а и връща нормализирани данните. e.g:

USE     tempdb

GO
SET NOCOUNT ON
GO

IF OBJECT_ID('UserPermissions') IS NOT NULL DROP TABLE UserPermissions
GO
CREATE TABLE UserPermissions (
uid INT NOT NULL
, perm1 INT NULL
, perm2 INT NULL
, perm3 INT NULL
, perm4 INT NULL
-- , CONSTRAINT FK_UserPermissions_Users
-- FOREIGN KEY uid
-- REFERENCES Users(uid)
)
GO

INSERT UserPermissions
SELECT 1, 1, NULL, 2, NULL UNION ALL
SELECT 2, NULL, NULL, 2, NULL UNION ALL
SELECT 3, NULL, 3, NULL, NULL UNION ALL
SELECT 4, -1, -1, -1, -1
GO

IF OBJECT_ID('UserPermissionsList') IS NOT NULL DROP VIEW UserPermissionsList
GO
CREATE VIEW UserPermissionsList
AS
SELECT uid
, 'perm1' AS type
, perm1 AS perm
FROM UserPermissions
UNION ALL
SELECT uid
, 'perm2' AS type
, perm2 AS perm
FROM UserPermissions
UNION ALL
SELECT uid
, 'perm3' AS type
, perm3 AS perm
FROM UserPermissions
UNION ALL
SELECT uid
, 'perm4' AS type
, perm4 AS perm
FROM UserPermissions
GO

SELECT uid, perm
FROM UserPermissionsList
WHERE type = 'perm1'
GO

cheers,
</wqw>

Отговор
в отговор на wqw #11

Re: column name as a parameter

Да бе, сега ми просветна...
просто ще си нормализирам базата, включително и матрицата с правата за достъп вместо да се мъча с екзотични решения
все си мислех че правя нещо кой знае колко хитро, а то се оказа голяма глупост


Отговор