Problem with filtered WHERE clause in Stored Procedure after converting to Dynamic Procedure

Hello, 

Running SQL SERVER 2008

I have a stored procedure that pages and provides a couple of WHERE clauses using COALESCE()function, and a ‘Split’ UserDefinedFunction (to allow an array of parameters).  It all works well till I convert it to a dynamic procedure to allow for a sortExpression parameter.  The procedure runs but not as expected.

The Parameters in the WHERE clause:

1) @CategoryID with the COALESCE()function (which is an optional parameter), so if its NULL, it bypasses and, 2) @MetroArray with the Split function allows for a single or an array of parameters e.g. (1,2,3).
@CategoryID       int = null,
@MetroArray       nvarchar(100), 

Here is the working, non-dynamic WHERE clause:

 WHERE (CategoryID = COALESCE(@CategoryID, CategoryID)
      -- NOTE: conpensate for null @CategoryID      
	OR (@CategoryID IS NULL AND CategoryID IS NULL))      
	AND MetroID IN (SELECT CONVERT(int, Value) FROM Split(@MetroArray,','))

Here is the NOT WORKING dynamic WHERE clause:

WHERE (CategoryID = COALESCE(' + CONVERT(nvarchar(10), @CategoryID) + ', CategoryID)
       OR (' + CONVERT(nvarchar(10), @CategoryID) + ' IS NULL AND CategoryID IS NULL))
      AND MetroID IN (SELECT CONVERT(int, Value) FROM Split(' + @MetroArray + ','',''))
The 2 problems that occur when dynamic:
1) In the case of @CategoryID and passing NULL, than 0 results are returned instead of bypassing.
2) And with @MetroArray, passing a single value (1) works, but when passing an array (1,2,3), an error of: 
Procedure or function Split has too many arguments specified.  

 

And the Split Function from:

http://www.4guysfromrolla.com/ASPScripts/PrintPage.asp?REF=%2Fwebtech%2F031004-1.shtml
UDF code here:
http://www.4guysfromrolla.com/webtech/code/udf.txt 
 
I think/thought the problem is the placement of the commas and/or quotes (',') in the dynamic creation.  
But after struggling with this for some time now and pulling my hair, I can’t seem to resolve this. 
Any assistance would be greatly appreciated.
Thank you in advance,
Ronnie
 
0
RonnieK
5/3/2009 4:19:02 AM
asp.net.sql-datasource 29906 articles. 0 followers. Follow

19 Replies
713 Views

Similar Articles

[PageSpeed] 31

Hi,

For starters, why don't you post the code for the stored procedure so we can see what you have and try to figure out what's wrong.

Also, what version of SQL Server are you using?

Don


Don Kiely, MCP, MCSD
In the Last Frontier, Interior Alaska
Please post questions and replies to the forum! And remember to MARK AS ANSWER when someone definitively answers a question or resolves a problem!
0
donkiely
5/3/2009 4:59:57 AM

Don, Sorry for the unformatted post.  I cleaned it up a bit, hope its better.

Also, I'm running SQL Server 2008

Ronnie

0
RonnieK
5/3/2009 5:24:35 AM

 hi,

1) In the case of @CategoryID and passing NULL, than 0 results are returned instead of bypassing.
not clear what you trying to do here 
2) And with @MetroArray, passing a single value (1) works, but when passing an array (1,2,3), an error of:  
 '''+@MetroArray+ ''' -- you need to add '' ''


Bryian Tan
MCP, MCAD
0
BryianTan
5/3/2009 5:43:58 AM

Bryian,

Thanks for that..!!! 2) is fixed.

As for 1).. I'm trying to combine 2 overloaded methods that used 2 SPROCS, into 1 Method and use 1SPROC.

Originally I had 2 methods:

public static List<Profile> GetProfiles(string metroArray)
{
}

public static List<Profile> GetProfiles(int categoryID, string metroArray)
{
  if (categoryID <= 0)
    return GetProfiles(metroArray);
}

The first method called a SPROC with just @MetroArray

The 2nd called one with @CategoryID and @MetroArray as params

 

So if in my ObjectDataSource the CategoryID param was not declared, 0 will be set as the value and then the BLL will access a different method.

In the case above 2 sprocs and 2 overloaded methods are not a major deal, but I only used 2 params in this post , I've cut alot of other params required in the WHERE clause:

RegionID, NeighborhoodID, FeatureID, and more to come..... Using the above model, I'd have to create a SPROC for each variation of input params and end up with many methods... Tongue Tied  I'm learning as I go here and I'm sure there are other alternatives... I just don't know of them.  Idea's are openly welcome..! Smile

I came across the COALESCE() function and with that it allowed me to combine the WHERE clause while allowing NULL values to pass for some of the params and having 1 SPROC.

Here's the article that I learned about COALESCE and explains the required OR statement to compensate for a null param: OR (@CategoryID IS NULL AND E.CategoryID IS NULL)

http://stackoverflow.com/questions/317377/sql-if-statement-in-where-clause-for-searching-database

And it all worked till I needed to allow for a sortExpression which put me in the unfortunate situation of putting it in a dynamic query.

 

I think this is not converting @CategoryID to NULL properly if it's NULL.  I think it's converting it to the charters 'null' instead of NULL, and thats what I need here.  This is added to compensate in case @CategoryID is not passed:

'OR (' + CONVERT(nvarchar(10), @CategoryID) + ' IS NULL AND E.CategoryID IS NULL))'

I hope my explanation makes sense. 

Thanks again for the fix on the @MetroArray !,

Ronnie

0
RonnieK
5/3/2009 7:22:43 AM

 hi,

try if you can use varchar for @categoryid, something like below

DECLARE @CategoryID varchar(10), @tsql varchar(500)
SET @CategoryID = 6

SET @tsql = '
WHERE ((CategoryID = COALESCE('+isnull(@CategoryID,'null')+', CategoryID) )
OR (CONVERT(nvarchar(10),'+isnull(@CategoryID,'null')+') IS NULL AND CategoryID IS NULL)
) '
print @tsql
  
Bryian Tan
MCP, MCAD
0
BryianTan
5/4/2009 3:14:20 AM

That did it...!!  Yes

I know my posts were long and detailed.  I really appreciate the time and attention to this.  Preferably I didn't want to use dynamic sql, but no alternative when adding a @SortExpression

Once again, Thank you Bryian..!  

 Ronnie

0
RonnieK
5/4/2009 4:05:57 PM

If your SortExpression have limited number of choices, then you may use CASE in the ORDER BY and avoid using dynamic SQL.


Beware of bugs in the above code; I have only proved it correct, not tried it.
(Donald Knuth)
0
Naom
5/4/2009 4:13:40 PM

Yes, there are only a few allowable expressions, and I ended up creating a method that validates and srubs the sort string.  But I'd much rather avoid the dynamic query and keep the benefit of the execution plan and all this piecemeal work.  Just not sure how to work in the CASE in t-sql..??

Say my available sort expressions were by:

@SortExpression = P.ProfileName ASC
@SortExpression = P.Rating DESC, P.ProfileName ASC
else
@SortExpression = P.Importance DESC, P.ProfileName ASC

and the query was something like:  

DECLARE @SortExpression nvarchar(100)
BEGIN
	SELECT * FROM
	(
		SELECT P.ProfileID, P.CategoryID, P.MetroID, P.ProfileName, P.Rating, P.Importance,
			ROW_NUMBER() OVER (ORDER BY @SortExpression) AS RowNum
		FROM Profiles P
		WHERE P.MetroID = @MetroID
	) Profiles
	WHERE Profiles.RowNum BETWEEN (@PageIndex*@PageSize+1) AND ((@PageIndex+1)*@PageSize)
END
 
Where/How would I add the CASE?
Thank you,
Ronnie

 

0
RonnieK
5/4/2009 5:03:33 PM

Somehow I only was able to find this http://forums.asp.net/p/691322/2764974.aspx#2764974 though I remember limno showed an answer on this problem also in his blog. Hopefully he'll join the discussion.


Beware of bugs in the above code; I have only proved it correct, not tried it.
(Donald Knuth)
0
Naom
5/4/2009 5:16:46 PM

 

BEGIN
SELECT * FROM
(
SELECT P.ProfileID, P.CategoryID, P.MetroID, P.ProfileName, P.Rating, P.Importance,
ROW_NUMBER() OVER (ORDER BY @SortExpression) AS RowNum
FROM Profiles P
WHERE P.MetroID = @MetroID
) Profiles
WHERE Profiles.RowNum BETWEEN (@PageIndex*@PageSize+1) AND ((@PageIndex+1)*@PageSize)

Order By Case @SortExpression
When 'P.ProfileName ASC' Then NULL
When 'P.Rating DESC, P.ProfileName ASC' Then P.Rating
When 'P.Importance DESC, P.ProfileName ASC' Then P.Importance
End DESC,
P.ProfileName ASC
END
 
When using a Case/When statement, it's important that each
branch (possible return value) actually returns the same data
type, otherwise you can run in to some hard to debug problems. 
In this case, the possible values are Rating and Importance. 
If both of these columns are the same data type, then this should
work out well for you.  If they are different, then let us know
what the data types are and we can help further.
 

-George
0
gmmastros
5/4/2009 5:25:01 PM

 To see what I mean about the "Case/When Data type mismatch problem".

 

SQL Server Case/when data type problems


-George
0
gmmastros
5/4/2009 5:29:43 PM

Very nice! I was trying to figure out how to switch between ASC/DESC using CASE statement and your query does it.

However, if we would need either ASC or DESC by the same field as two separate SortExpressions, do you see a way to do this without dynamic SQL?

Two separate queries in one SP?


Beware of bugs in the above code; I have only proved it correct, not tried it.
(Donald Knuth)
0
Naom
5/4/2009 5:43:31 PM

Thank you, I'll read up on your article on the mismatch, play with this and get a handle on using CASE.  If I can trouble you with one last question.  If had a couple other data types (Rate = money & OurPic = bit) and Rate needed to be sorted both ASC and DESC ..?  How would this be completed...?

Order By Case @SortExpression
              When 'P.ProfileName ASC' Then NULL
              When 'P.Rating DESC, P.ProfileName ASC' Then P.Rating
              When 'P.Importance DESC, P.ProfileName ASC' Then P.Importance

Note: ASC-->     When 'P.Rate ASC, P.ProfileName ASC' Then P.Rate
              When 'P.Rate DESC, P.ProfileName ASC' Then P.Rate
              When 'P.OurPick DESC, P.ProfileName ASC' Then P.OurPick
              End DESC,
         P.ProfileName ASC
 
Thank you,
Ronnie
0
RonnieK
5/4/2009 6:16:01 PM

It becomes  more complicated that way, but still possible.  The ASC/DESC part cannot be within the Case part of the statement, so you would need to put an additional part of the order by.

I tested this in my own database like this:

 

 

Select ManufactureDate, BusNumber
From   BusInformation
Order By Case @SortExpression
              When 'ManufactureDate DESC, BusNumber DESC' Then ManufactureDate
              When 'ManufactureDate ASC, BusNumber ASC' Then NULL
              End DESC,
         Case @SortExpression
              When 'ManufactureDate DESC, BusNumber DESC' Then NULL
              When 'ManufactureDate ASC, BusNumber ASC' Then ManufactureDate
              End ASC,
         Case @SortExpression
              When 'ManufactureDate DESC, BusNumber ASC' Then NULL
              When 'ManufactureDate ASC, BusNumber ASC' Then BusNumber
              End DESC,
         Case @SortExpression
              When 'ManufactureDate DESC, BusNumber DESC' Then BusNumber
              When 'ManufactureDate ASC, BusNumber ASC' Then NULL
              End ASC

  

Notice how I have 2 columns I "mess' with, but this translates in to a four part order by (each with a case).  It can start to get pretty messy, pretty quick. 

Basically, the first 2 handle ManufactureDate, the first sorts DESC and the second sorts ascending.  The last 2 deal with BusNumber ascending or descending.  The real trick is.... if we want to sort ManufactureDate ASC, then we return NULLS from the case expressions for the descending part (so that all the rows will sort the same). 

 

Make sense?


-George
0
gmmastros
5/4/2009 6:18:06 PM

RonnieK:
Rate needed to be sorted both ASC and DESC
 

Numbers are easy (and money really is a number data type).

To change the sort order, simply order by the negative of the value.  Ex:

 

  

Declare @TEmp Table(Rate Money)

Insert Into @Temp Values(1.23)
Insert Into @Temp Values(2.34)
Insert Into @Temp Values(-5.24)

Select * From @Temp Order By Rate DESC

Select * From @Temp Order By -1 * Rate ASC

 

Notice how both queries sort the same.  The only difference is multiplying the value by -1.  So, in your query...

 

 

Order By Case @SortExpression
              When 'P.ProfileName ASC' Then NULL
              When 'P.Rating DESC, P.ProfileName ASC' Then P.Rating
              When 'P.Importance DESC, P.ProfileName ASC' Then P.Importance
              When 'P.Rate ASC, P.ProfileName ASC' Then -1 * P.Rate
              When 'P.Rate DESC, P.ProfileName ASC' Then P.Rate
              When 'P.OurPick DESC, P.ProfileName ASC' Then P.OurPick
              End DESC,
         P.ProfileName ASC

  

The bigger problem you are going to have is the various data types involved.  Can you post all of the data types involved in your query (just to make sure you won't have a data type problem).

 


-George
0
gmmastros
5/4/2009 6:24:59 PM

Clever..!!!

Select * From @Temp Order By -1 * Rate ASC

Thanks for the examples, very helpful.

 

These should be all I'm going to work with:  nvarchar, bit, money, int

Possably ReleaseDate = datetime..:

When 'P.ReleaseDate DESC, P.ProfileName ASC' Then P.ReleaseDate
 
0
RonnieK
5/4/2009 6:45:44 PM

 Please read the blog I pointed you to earlier.  It's important.  Very important.

 

What you will need to do is to convert your data to nvarchar (the common denominator for your data type).  The next problem is with the converted value.  You see, when you convert a number to a string, it will sort like a string, 1, 10, 2 etc.... so, you should zero-pad your numeric values.

 

Ex:

 

  

Order By Case @SortExpression
              When 'P.ProfileName ASC' Then NULL
              When 'P.Rating DESC, P.ProfileName ASC' Then Right('0000000000' + Convert(VarChar(10), P.Rating), 10),
              When 'P.Importance DESC, P.ProfileName ASC' Then P.Importance
              When 'P.Rate ASC, P.ProfileName ASC' Then -1 * P.Rate
              When 'P.Rate DESC, P.ProfileName ASC' Then P.Rate
              When 'P.OurPick DESC, P.ProfileName ASC' Then P.OurPick
              End DESC,
         P.ProfileName ASC
 

 Notice the way I zero-paded the Rating column.  This will return a string like this...  0000009876.  This is a string, but more importantly, it will sort like it's a number (because of hte zero-padding).  You'll need to convert each column in the case statement to a string, and then make sure it still sorts properly.

 

 


-George
0
gmmastros
5/4/2009 7:09:18 PM

Reading and testing right now...

Still, thanks for the additional explanations and perspective on converting to nvarchar.  I'm sure this will answer my questions as I test this using CASE.

Much appreciated,

Ronnie

0
RonnieK
5/4/2009 7:26:13 PM

 You're welcome.

 


-George
0
gmmastros
5/4/2009 7:31:50 PM
Reply:

Similar Artilces:

How to convert Sql Server Stored Procedures into Oracle Stored Procedures
Hi All, I am migrating from sql server2000 to oracle. I have moved all table into oracle manually. Now I need to move stored procedure. I don't know how to convert sql server stored procedure into oracle stored procedure form. Is there any tool which will convert directly. Please some one help me. Thank you.    Hi there,Please use the tool bellow, which does the job you want. http://www.swissql.com/products/sqlserver-to-oracle/sql-server-to-oracle.html thanks sharp guy...

Problem with SQL DataSource and Stored Procedure
I'm trying to call a Stored procedure as my SQLDataSource update command but I'm getting the following error: "Procedure or function ProcessTravelPolicy has too many arguments specified." The Update Command looks like this:                     UpdateCommand="ProcessTravelPolicy" UpdateCommandType="StoredProcedure">                     <UpdateParameters>        &n...

Permissions problem on stored procedure with dynamic sql
I have a stored procedure which executes a statement dynamically. Here is the query: exec ('select objid from table_user where objid in (' + @userlist + ') and x_status_flag = 1 order by x_status_change_time asc') @userlist is a varchar parameter passed which is a set of comma seperated integers : "268435692,268436102,268436361,268436445,268437173" I have a specific user which runs this procedure which I have granted execute permisssions for the procedure but I get a permissions error because the use...

dynamic sql where and order by clauses in stored procedure
Hi, I hope some one can help me. I have a stored procedure (Microsoft SQL 2005 Express Edition) that I want users to be able to dynamically set the, group by, order by (@orderby) and where clause (@where). I have managed to get the group by to work but can't seem to get the where and order by to work. Here's my stored procedure. Any idea how this can be done? ALTER PROCEDURE [dbo].[sp_aggregate]     -- Add the parameters for the stored procedure here @finfileid int,     @phaseid int, @supplierid int, @measurementid int, @roleid int, @...

VB.NET SQL stored procedure: procedure has no parameters and arguments were supplied
VB.NET SQL stored procedure: procedure has no parameters and arguments were supplied Please assist me:This erorr message is produce when calling the stored procedure in vb.netProcedure AutomateMatterNumber has no parameters and arguments were supplied."MS SQL 2000stored procedure:*/CREATE PROCEDURE dbo.AutomateMatterNumber ASDECLARE @nextMtr AS BIGINTDECLARE @dtToday AS DATETIMEIF NOT EXISTS(SELECT * FROM tempMatter WHERE DATEDIFF(dd,DateSet,GETDATE())=0 )BEGINDELETE FROM tempMatter-- incase there are some old recordsSELECT TOP 1 @nextMtr= CONVERT(BIGINT, MatterNumber) + 1 ,@dtTod...

help with converting MSSQL Stored Procedure to Oracle PL/SQL Procedure
Hi there,I have replicated our Oracle db structure and data on SQL Server 2005. I have the following MSSQL Stored Proc, which works just perfectly! I'm basically using one proc with 3 statements inside, each one that assigns values to Output Paramters that I will pick up in my c# code.1 set ANSI_NULLS ON 2 set QUOTED_IDENTIFIER ON 3 GO 4 CREATE PROCEDURE [dbo].[Employee_GetAllDetails] 5 @EmployeeID BIGINT, 6 @Has_Entry BIT OUTPUT, 7 @Has_Projects BIT OUTPUT, 8 @First_Name VARCHAR(30) OUTPUT, 9 @Last_Name VARCHAR(30) OUTPUT, 10 ...

SQL Stored Procedure to MySQL Stored Procedure Conversion
Hi, I am trying to convert a stored procedure written for sql to one that will work in mysql. I understand that I have to set the variables as IN , but I don't know what to do with the rest of the code. The following is the sql stored procedure that I am trying to convert to msql stored procedure: CREATE PROCEDURE Register_User (@userName Varchar(50), (@PassWord Varchar(50), (@FirstName Varchar(50), (@LastName Varchar(50) ) AS IF EXISTS(SELECT u_ID FROM User_ID Where u_UserName=@UserName) RETURN -1 ELSE INSERT User_ID( u_User...

SQL Stored Procedure Issue
This is the Stored Procedure below ->  SET QUOTED_IDENTIFIER ON GOSET ANSI_NULLS ON GO /****** Object:  Stored Procedure dbo.BPI_SearchArchivedBatches    Script Date: 5/18/2007 11:28:41 AM ******/if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[BPI_SearchArchivedBatches]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)drop procedure [dbo].[BPI_SearchArchivedBatches]GO /****** Object:  Stored Procedure dbo.BPI_SearchArchivedBatches    Script Date: 4/3/2007 4:50:23 PM ******/ /****** Object:  Stored Proc...

Stored Procedures with result set Problem in Dynamic SQL?
Hi, I am facing following problem when i create the datawindow datasource as Stored procedure. Using Oracle 9i,PowerBuilder 9. i want to create a dynamic sql in SP that will return the output to the datawindow..But it is showing error while compiling.. Any idea ? Sample coding is given below: ------------------------------ CREATE OR REPLACE PACKAGE PKG_DW IS TYPE DW_OUTPUT IS RECORD(EMP_NO INTEGER,NAME VARCHAR2(200)); TYPE CUR_RETURN IS REF CURSOR RETURN DW_OUTPUT; END; CREATE OR REPLACE PROCEDURE SP_DW ( AS_JOB IN VARCHAR2 Default NULL, DW_OUTPUT OUT PKG_DW.CUR_RE...

sql count using stored procedure withing stored procedure
I have a stored procedure that among other things needs to get a total of hours worked. These hours are totaled by another stored procedure already. I would like to call the totaling stored procedure once for each user which required a loop sort of thing for each user name in a temporary table (already done) total = result from execute totaling stored procedure Can you help with this Thanks It would be easier if you can change the stored procedure into a function. Once you do that, the total can be calculated easily with something like thisSelect Sum(dbo.CalculateHours(User...

MS SQL stored procedures inside another stored procedure
Hi,  Do you know how to write stored procedures inside another stored procedure in MS SQL.   Create procedure spMyProc inputData varchar(50) AS  ----- some logical    procedure spMyProc inputInsideData varchar(10) AS    --- some logical   ---  go ------- What exactly are tou trying to do? ***********************Dinakar NethiLife is short. Enjoy it.*********************** Like Function, you can have one function inside another another function. Function1 () {    Function2() } How about store procedure ? spProc1 { &n...

Linq to SQL and stored procedure with dynamic sql
I have a stored procedure like create proc test as ..... set @sql = 'select ' + .... + ' from ....' exec(@sql)The select list is dynamically (in fact, pivot table). However, after drag the stored procedure to dbml design view and called, the stored procedure only return an integer.How to get the result set of the stored procedure when using dbml?Thanks,  Is this the only SELECT statement that @sql gets?  I created a simple example and it performed as I would expect returning a complete recordset....I'm wondering if your stored proc is returning 2 record se...

Problem accessing SQL Stored Procedure From .Net using hibernate object
Hi, I am calling a SQL Stored procedure from .net application using Hibernate object, but somehow its telling me "The 'callable' attribute is not declared.", I am not sure what's wrong I have done here. Will really appreciate if someone can help me for this. Herewith I am providing my Stored Procedure, my .hbm file and code to call it. can someone pls tell me what's wrong in this? Also, if possible, pls tell me how to set result in a list object. Thanks in advance, ######################################### MY STORED PROCEDURE : ALTER PROCEDURE [dbo].[RulesDetails_...

Calling a stored procedure inside another stored procedure (or "nested stored procedures")
Hi all - I'm trying to optimized my stored procedures to be a bit easier to maintain, and am sure this is possible, not am very unclear on the syntax to doing this correctly.  For example, I have a simple stored procedure that takes a string as a parameter, and returns its resolved index that corresponds to a record in my database. ie exec dbo.DeriveStatusID 'Created' returns an int value as 1 (performed by "SELECT statusID FROM statusList WHERE statusName= 'Created')  but I also have a second stored procedure that needs to make reference to&n...

Web resources about - Problem with filtered WHERE clause in Stored Procedure after converting to Dynamic Procedure - asp.net.sql-datasource

Facebook Begins Converting Users To HTTPS
Are you willing to sacrifice a little bit of speed for a lot more safety? Facebook is asking that very question with its announcement that it ...

Facebook No Longer Converting Groups Into Pages
Back when Facebook first launched Facebook Pages, many businesses and brands who had built up substantial audiences in their Facebook Groups ...

Vert - simply converting for iPhone, iPad, and iPod touch on the iTunes App Store
Get Vert - simply converting on the App Store. See screenshots and ratings, and read customer reviews.

Converting SIM Card to Micro SIM Card - Flickr - Photo Sharing!
Place new Micro SIM into the iPhone SIM card tray

Ayaan Hirsi Ali on Converting Muslims to Christianity - YouTube
Complete video at: http://fora.tv/2010/07/29/Nomad_From_Islam_to_America_with_Ayaan_Hirsi_Ali Ayaan Hirsi Ali explains her support of missionary ...

Click go fears of converting print files
Is there a way to convert a print queue item to a .RTF or .PDF file? I like to save or email them. - The Sydney Morning Herald

Sudanese woman ordered to hang under sharia law for converting to Christianity gives birth
Khartoum, Sudan: A Christian Sudanese woman sentenced to hang for apostasy has given birth in jail, a Western diplomat said on Tuesday.

Imams warn against radicalism to Aboriginal inmates converting to Islam
The prison system has enlisted the help of ASIO to crack down on radicalisation behind bars amid revelations that Aboriginals are converting ...

Converting the world's companies one by one - The Science Show - ABC Radio National (Australian Broadcasting ...
Image: Trucks carrying logs make their way up a road in Jambi, Indonesia. A vast area of the Sumatran forest, and orangutan habitat, is being ...

Converting Churches Into Homes Is The Latest Hollywood Trend
You don't have to be a believer to be moved by the beauty of a church.

Resources last updated: 12/22/2015 12:37:24 AM