У меня есть эта строка, которую я получаю из приложения A .NET, B, C, D, E, F,
Я хотел записать оператор выбора sql как
set @string = 'A,B,C,D,E,F'
select * from tbl_test
where tbl_test.code in (@string)
Эта работа привычки в T-SQL, потому что это использует @string
как одна строка это не разделяет значения. Есть ли какие-либо способы, которыми я могу сделать это?
Думаю, самым простым способом сделать это будет динамическая генерация SQL:
// assuming select is a SqlCommand
string[] values = "A,B,C,D,E,F".Split(',');
StringBuilder query = new StringBuilder();
query.Append("select * from tbl_test where tbl_test.code in (");
int i = 0;
foreach (string value in values) {
string paramName = "@p" + i++;
query.Append(paramName);
select.Parameters.AddWithValue(paramName, value);
}
query.Append(")");
select.CommandText = query.ToString();
// and then execute the select Command
# create an array with FALSE and lines from the file
unset list
while read -r line
do
list+=("FALSE")
list+=("$line")
done < data_file
# set some entries to TRUE
for entry in 0 2 5 11 12 19
do
list[entry]="TRUE"
done
# display the dialog
ans=$(zenity --list --text "Show List" --checklist --column "Pick" --column "List" "${list[@]}" --separator=":")
echo $ans
-121--1948912- Для получения DPI можно использовать следующую функцию javascript.
<script type="text/javascript">
var dpi = {
v: 0,
get: function (noCache) {
if (noCache || dpi.v == 0) {
e = document.body.appendChild(document.createElement('DIV'));
e.style.width = '1in';
e.style.padding = '0';
dpi.v = e.offsetWidth;
e.parentNode.removeChild(e);
}
return dpi.v;
}
}
alert(dpi.get(true)); // recalculate
alert(dpi.get(false)); // use cached value
</script>
Однако я думаю, что он всегда будет возвращать 96
на оконных машинах.
Насколько мне известно, операционная система не имеет пути определять фактические физические размеры видового экрана. Таким образом, вполне может быть, что программное обеспечение на самом деле не может знать реального DPI.
Однако профессионалы в определенных областях проверяют соответствие DPI на экране реальному DPI. В этом случае вышеуказанного javascript, вероятно, будет достаточно.
Примечание:
Протестировал вышеуказанный код в Opera 9, IE6 & 7 и Firefox 3,6 на WinXP и Win2k.
Update:
Добавлен параметр noCache. Но я сомневаюсь, что это даст какой-то эффект. Я протестировал его с помощью zoom в FireFox и Opera на вышеупомянутых версиях окон, и они продолжают цитировать DPI как '96', независимо от величины zoom. Интересно было бы посмотреть, что из этого делают мобильные устройства.
Предложение dynamic IN означает:
DECLARE @SQL NVARCHAR(4000)
SET @SQL = 'SELECT * FROM tbl_test t
WHERE t.code IN (@string_param)
BEGIN
EXEC sp_executesql @SQL N'@string_param VARCHAR(100)', @string
END
. Имейте в виду, что sp _ executesql
имеет значение 2005 +, и является предпочтительным, так как будет кэшировать план запроса. Дополнительные сведения см. в разделе Проклятие и благословения динамического SQL , но помните о атаках впрыска SQL .
Создайте функцию, определяемую пользователем, которая принимает строку на вход и возвращает таблицу:
create function [dbo].[f_SplitString] (@str as varchar (1000))
returns @t table (value varchar (50))
etc...
Затем настройте оператор Select:
select * from tbl_test
where tbl_test.code in (select value from f_SplitString(@string))
Вот функция, которая возвращает строку с разделителями в виде набора строк
set @string = 'A,B,C,D,E,F'
select * from tbl_test
where tbl_test.code in (select r from ftDelimitedAsTable(',',@string )
--/*----------------------------------------------------------------
Create FUNCTION [dbo].[ftDelimitedAsTable](@dlm char, @string varchar(8000))
RETURNS
--------------------------------------------------------------------------*/
/*------------------------------------------------------------------------
declare @dlm char, @string varchar(1000)
set @dlm=','; set @string='t1,t2,t3';
-- tHIS FUNCION RETUNRS IN THE ASCENDING ORDER
-- 19TH Apr 06
------------------------------------------------------------------------*/
--declare
@table_var TABLE
(id int identity(1,1),
r varchar(1000)
)
AS
BEGIN
-- a.p --
--Modified 18th Nov. 04
declare @n int,@i int
set @n=dbo.fnCountChars(@dlm,@string)+1
SET @I =1
while @I <= @N
begin
--print '@i='+convert(varchar,@i)+ ' AND INSERTING'
insert @table_var
select dbo.fsDelimitedString(@dlm,@string,@i)
set @I= @I+1
end
--PRINT '*************** ALL DONE'
if @n =1 insert @TABLE_VAR VALUES(@STRING)
--select * from @table_var
delete from @table_var where r=''
return
END
USE [QuickPickDBStaging]
GO
/****** Object: UserDefinedFunction [dbo].[fsDelimitedString] Script Date: 02/22/2010 12:31:37 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
Create function [dbo].[fsDelimitedString](
@DelimiterStr varchar(100)
,@str varchar(4000)
,@pos int=1)
returns varchar(4000)
as
/*
AP -- Dec 2003
Declare @DelimiterStr varchar(4000),@str varchar(4000) ,@pos int
set @delimiterStr = '-'
set @pos=10
set @str ='wd-1-22-333-4444-55555-666666-q-9'
*/
Begin
declare @rx varchar(4000)
set @rx=''; set @pos=@pos-1
IF DBO.fnCountChars(@DelimiterStr,@str) > 0
Begin
if dbo.fnCountChars(@delimiterStr,@str) < @pos
begin
set @rx= null
goto nulls
end
declare @i1 int,@tPos int,@ix int
set @ix=1
set @tPos=0
while @tpos <> @pos
Begin
set @ix=charindex(@DelimiterStr,@str,@ix+1)
if @ix > 0 set @tpos=@tpos+1
end
set @i1= charindex(@DelimiterStr,@str,@ix+1)
if @i1=0
set @rx=substring(@str,@ix+1,len(@str)-@ix)
else
begin
if @ix=1
set @rx=substring(@str,@ix,@i1-@ix)
else
set @rx= substring(@str, @ix+1,@i1-@ix-1)
end
-- 'print 'ix='+convert(varchar,@ix)+' @i1='+convert(varchar,@i1)+' @rx='+@rx
RETURN @RX
end
nulls:
RETURN @rx
end
У вас есть несколько вариантов:
IN
IN
, либо лучше просто JOIN
оператор (среди других реализаций я предпочитаю SQL User Defined Function to Parse a Delimited String). Ваш код будет выглядеть так:
select tbl_test.*
from tbl_test
inner join fn_ParseText2Table(@string) x
on tbl_test.code = x.txt_value
SQL
. Вы можете упростить задачу с помощью встроенных функций sql:
set @string = 'A,B,C,D,E,F'
select * from tbl_test
where CHARINDEX(ISNULL(tbl_test.code, 'X'), @string) > 0
PATINDEX можно использовать, если вам нужно более одного символа.
Ничего простого. Вы можете написать функцию, которая будет принимать этот список и разделять его на таблицу, которую вы можете запросить в операторе IN ().
3 варианта
Очень часто задаваемый вопрос! Вам нужна функция с табличным значением.
Но не изобретайте велосипед, написав свое собственное, я нашел десятки только с помощью Googling sql split
. Вот один от Microsoft:
http://code.msdn.microsoft.com/SQLExamples/Wiki/View.aspx?title=StringArrayInput
Я использовал для этого динамический SQL, но это означало, что мне пришлось копать код и копируйте его в каждое новое приложение. Теперь мне даже не нужно об этом думать.